【问题标题】:Java parallel calculation / threadingJava并行计算/线程
【发布时间】:2016-08-23 19:38:07
【问题描述】:

这是我的问题:假设我有 200 个人。目标是优化该人群。每个人都有几个参数,这些参数用于为该个人分配一个值(质量级别)。该值的计算可以为每个人单独完成,但每个人需要几秒钟。我的笔记本电脑有 4 个处理器,我注意到使用多个线程(通过 Runnable、1 个主线程、7 个个人线程、7 个个人同时处理然后接下来的 7 个)可以将计算速度提高 3 倍。但是,我对线程一无所知,并且我的实现存在缺陷。程序很可能会终止,但也有可能会冻结(这可能会花费我 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();

        // ...
    }
}

【问题讨论】:

  • 见执行者。和 ExecutorService

标签: java multithreading parallel-processing runnable


【解决方案1】:

您不需要手动创建和启动所有线程。查看 java.util.concurrent.CompletionService。您可以创建仅执行计算的小段代码,然后提交到此 CompletionService,然后它将运行您的所有任务,您可以在完成时查看它。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-08
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多