3

我正在尝试编写一个线程,当我通过主线程中的适应度对现有染色体进行排序时,我可以将机器人的测试和进化委托给它。下面是初始的健身方法。我在这里要做的是让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();
}

}

候选测试类

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;
}

}

4

3 回答 3

1

首先,您没有启动robotHandler线程。所以你的主线程到达wait(),然后没有其他线程来通知它。

其次,你调用wait()任何initialFitness属于的类,但你调用notifyAll(). RobotInterface所以RobotInterface会通知所有等待它的人(没有人),你的主代码将继续等待。你需要调用你调用notifyAll()的同一个对象wait()

我建议

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

   candidateTest.notify();
于 2013-03-13T15:37:00.303 回答
1

从未见过线程从哪里开始。尝试:

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

所以你的 notifyAll() 永远不会被调用

于 2013-03-13T15:34:27.073 回答
0

Nathanial 一针见血,但如果您刚刚开始使用 Java 并发,我建议您使用 java.util.concurrent 包。为您找到了一篇关于 DZone 的不错的初学者文章:http: //java.dzone.com/articles/lazy-developers-introduction

于 2013-03-13T15:42:38.433 回答