Java并行计算/线程

时间:2016-04-28 20:26:23

标签: java multithreading parallel-processing runnable

这是我的问题:我的人口可以说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();

        // ...
    }
}

1 个答案:

答案 0 :(得分:0)

您无需手动创建和启动所有线程。查看java.util.concurrent.CompletionService。您可以创建只进行计算的小块代码然后提交给此CompletionService,然后它将运行您的所有任务,并在完成后查看它。

我建议你看一下ExecutorCompletionService和Executors类。他们会帮助你