2013-03-13 36 views
2

我試圖編寫一個線程,我可以委託測試和機器人進化,同時通過主線程中的健身對現有染色體進行排序。以下是最初的健身方法。我想在這裏做的是每個基因組由一個robotHandler進行測試,因爲測試長度爲30到40秒。我只會在任何時候運行這些線程之一。因爲執行線程而陷入等待()返回

目前我似乎陷入intialFitness方法的wait()部分。這是我多線程的第一次嘗試,所以對於如何調試問題或者是否有人能夠發現這個問題將會非常有幫助

RobotInterface類目前只是一個測試類,我已經註釋掉了log4j和睡眠聲明,試圖排除這些了(順便說一句的log4j沒有登錄線程什麼,如果可以幫助)

public synchronized ArrayList<Genome> initialFitness(ArrayList<Genome> population) 
{ 
    for (int i = 0; i < population.size(); i++ ) 
    { 
     candidateTest = new CandidateTest(population.get(i)); 
     Thread robotHandler = new Thread(new RobotInterface(candidateTest)); 
     while(! (candidateTest.finishedYet())) 
     { 
      try 
      { 
       wait(); 
      } 
      catch (InterruptedException e) 
      { 
       logger.debug("The initialFitness method was interrupted, this shouldn't happen"); 
      } 
     } 
     population.set(i, candidateTest.getCandidate()); 
    } 
    return population; 
} 

import org.apache.log4j.Logger; 
import org.apache.log4j.PropertyConfigurator; 
import java.util.Random; 

的RobotInterface類

public class RobotInterface implements Runnable 
{ 
// create a serial connection 
// transmit a string and check for response 
// wait for evaluation 
// take evaluation 
private CandidateTest candidate; 
private Random rng = new Random(); 

//protected static Logger logger = Logger.getLogger("Thread" + Thread.currentThread().getName()); 

public RobotInterface(CandidateTest test) 
{ 
    this.candidate = test; 
    //PropertyConfigurator.configure("log4j.properties"); 
} 

public void evaluate (Genome genome) 
{ 
    //send to robot and return fitness 
    genome.setFitness(rng.nextDouble()); 
    //logger.debug("fitness is " + genome.getFitness()); 
    try 
    { 
     //logger.debug("Thread sleeping for 4 seconds"); 
     //Thread.sleep(4000); 
    } 
    catch(Exception E) 
    { 

    } 

} 

public void run() 
{ 
    //logger.debug("entering run of Robot Interface"); 
    //logger.debug("Send Genome via serial and wait for a response"); 
    Genome testSubject = candidate.getCandidate(); 
    evaluate(testSubject); 
    candidate.finished(); 
    notifyAll(); 
} 

}

的CandidateTest類

public class CandidateTest 
{ 
private volatile Genome candidate; 
private volatile boolean testFinished = false; 

public CandidateTest(Genome g) 
{ 
    candidate = g; 
} 

public synchronized Genome getCandidate() 
{ 
    return candidate; 
} 

public synchronized void finished() 
{ 
    testFinished = true; 
} 

public synchronized boolean finishedYet() 
{ 
    return testFinished; 
} 

}

+0

我想你或者需要/意思是使用Thread.sleep(

+0

我想你可能只是回答了這個問題,我忘了該死的線程。我不是嗎? – SMC 2013-03-13 15:35:13

回答

1

首先,你是不是開始robotHandler線程。所以你的主線程到達wait(),然後沒有其他線程來通知它。

其次,您致電wait()在任何類initialFitness屬於,但您致電 notifyAll()。所以RobotInterface會通知所有等待它的人(沒有人),你的主代碼將繼續等待。您需要在與wait()相同的對象上調用notifyAll()

我建議

synchronized(candidateTest) { 
    candidateTest.wait(); 
} 

candidateTest.notify(); 
+0

對不起,我認爲我一直在尋找代碼太久。你是否建議我在這種情況下讓候選測試可以運行? – SMC 2013-03-13 15:55:51

+1

是的,我真的看了太久,我完全消隱synchronized(){} vs synchronized methodName()。感謝您的幫助,修改candidateTest.wait()並將notifyAll()移入CandidateTest的完成方法已解決該問題。再次,謝謝你! – SMC 2013-03-13 16:12:54

1

沒見過其中線程啓動。嘗試:

Thread robotHandler = new Thread(new RobotInterface(candidateTest)).start(); 

所以你notifyAll的()不會被調用