我正在尝试编写一个线程,我可以将机器人的测试和演变委托给我,同时我在主线程中通过适应性对现有染色体进行排序。以下是最初的健身方法。我想在这里做的是让每个基因组由robotHandler测试,因为测试时间长达30-40秒。我将只在任何给定时间运行其中一个线程。
目前我似乎陷入了intialFitness方法的wait()部分。这是我对多线程的第一次尝试,所以有关如何调试问题的任何帮助,或者是否有人能够发现这将是非常棒的问题
RobotInterface类目前只是一个测试类,我已经注释掉了log4j和sleep声明来尝试并排除它们(顺便说一句,如果有帮助的话,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 Class
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 :(得分:1)
从未见过Thread的启动位置。尝试:
Thread robotHandler = new Thread(new RobotInterface( candidateTest)).start();
所以你的notifyAll()永远不会被调用
答案 1 :(得分:1)
首先,您没有启动robotHandler
主题。所以你的主线程进入wait()
,然后没有其他线程通知它。
其次,您在wait()
所属的任何课程上致电initialFitness
,但您在notifyAll()
上致电RobotInterface
。所以RobotInterface
会通知所有正在等待的人(无人),您的主要代码将继续等待。您需要在调用notifyAll()
的同一对象上调用wait()
。
我建议
synchronized(candidateTest) {
candidateTest.wait();
}
和
candidateTest.notify();
答案 2 :(得分:0)
Nathanial击中头部,但我建议使用java.util.concurrent包,如果你刚开始使用Java并发。在DZone上找到了一篇不错的初学者文章:http://java.dzone.com/articles/lazy-developers-introduction