2013-03-13 37 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的()不会被调用