这是我的问题:我的人口可以说200个人。目标是优化人口。每个人都有几个参数,这些参数用于为该个人分配一个值(质量等级)。该值的计算可以单独为每个人完成,但每个人需要几秒钟。我的笔记本电脑有4个处理器,我注意到通过使用多个线程可以快速完成3次计算(通过Runnable,1个主线程,7个线程用于个人,7个人同时处理,然后接下来的7个)。但是,我不了解线程,我的实现存在缺陷。最有可能的是,该程序将终止,但它也有可能冻结(这可能花费我1小时的计算时间)。我运行的其他程序越多,失败的可能性就越大。那么,如何正确地做到这一点?提前谢谢。
public class EntropyParralel
{
private static final int maxThreads = 7;
static final int populationSize = 200;
static Individual[] population;
static Thread[] threads;
static int finishedThreads;
static int startedThreads;
static class Individual implements Runnable
{
// ...
public void run()
{
eval();
finishedThreads += 1;
}
}
public static void newEntropy()
{
// ...
threads = new Thread[ population.length ];
for ( int i = 0; i < threads.length; i++ )
threads[i] = new Thread( population[i] );
startedThreads = 0; finishedThreads = 0;
while( finishedThreads < threads.length )
{
if ( startedThreads - finishedThreads < maxThreads && startedThreads < threads.length )
{
threads[startedThreads].start();
startedThreads += 1;
}
try
{
Thread.sleep(1);
}
catch(Exception e){}
}
sortPopulation();
// ...
}
}
编辑
没有找到关于简单数组计算的任何体面的ExecutorService示例。所以我继续使用Runnable和Thread。这次在每个主循环帧中通过thread.getState()。equals(Thread.State.TERMINATED)计算完成和新线程。它似乎工作正常。如果测试在一个较小的问题上运行超过10,000次迭代,并且它没有冻结。
public class EntropyParallel
{
private static final int maxThreads = 7;
static final int populationSize = 200;
static class Individual implements Runnable
{
// ...
public void run()
{
eval();
}
}
public static void newEntropy()
{
// ...
Thread[] threads = new Thread[ population.length ];
for ( int i = 0; i < threads.length; i++ )
threads[i] = new Thread( population[i] );
while( true )
{
int finishedThreads = 0; int availableThreads = 0;
for ( int i = 0; i < threads.length; i++ )
{
if ( threads[i].getState().equals(Thread.State.TERMINATED) )
finishedThreads += 1;
else if ( threads[i].getState().equals(Thread.State.NEW) )
availableThreads += 1;
}
if ( finishedThreads == threads.length )
break;
for ( int i = 0; i < threads.length; i++ )
{
if ( threads.length - finishedThreads - availableThreads >= maxThreads || availableThreads == 0 )
break;
if ( threads[i].getState().equals(Thread.State.NEW) )
{
threads[i].start();
availableThreads -= 1;
}
}
try
{
Thread.sleep(1);
}
catch(Exception e){}
}
sortPopulation();
// ...
}
}
答案 0 :(得分:0)
您无需手动创建和启动所有线程。查看java.util.concurrent.CompletionService。您可以创建只进行计算的小块代码然后提交给此CompletionService,然后它将运行您的所有任务,并在完成后查看它。
我建议你看一下ExecutorCompletionService和Executors类。他们会帮助你