首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java.util.concurrent :计算素数

java.util.concurrent :计算素数
EN

Stack Overflow用户
提问于 2010-01-28 09:27:07
回答 3查看 1.9K关注 0票数 2

我是java.util.concurrent包的新手。我创建了下面的程序,测试一个数字是否是素数,使用多点和单点策略。

代码语言:javascript
复制
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class IsPrime
        implements Runnable
    {
    private static final long UPPER_BOUND=100000;
    long value;//the number observed
    private IsPrime(long value)
        {
        this.value=value;
        }
    /** returns wether value is a prime number (simple and stupid method ) */
    private boolean isAPrimeNumber()
        {
        if(value==1 || value==2) return true;
        if(value%2L==0) return false;
        for(long i=3;i< value;++i)
            {
            if(this.value%i==0) return false;
            }
        return true;
        }

    @Override
    /** calls isAPrimeNumber */
    public void run()
        {
        boolean result=isAPrimeNumber();
        //if(result) System.out.println("["+this.value+"]");
        }

    /** loop from 3 to UPPER_BOUND, multithreaded */
    private static long loopMT() 
        {
        long now=System.currentTimeMillis();
        ExecutorService service=Executors.newFixedThreadPool(10); 

        for(long i=3;i< UPPER_BOUND;i+=2)
            {
            service.submit(new IsPrime(i));
            }
        service.shutdown();
        return System.currentTimeMillis()-now;
        }

    /** loop from 3 to UPPER_BOUND, NOT multithreaded */
    private static long loop() 
        {
        long now=System.currentTimeMillis();
        for(long i=3;i< UPPER_BOUND;i+=2)
            {
            new IsPrime(i).run();
            }
        return System.currentTimeMillis()-now;
        }

    public static void main(String[] args)
        {
        long n1=IsPrime.loop();
        long n2=IsPrime.loopMT();
        System.out.println(""+n1+" >>> "+n2);   
        }
    }

对于方法loopMT,是否正确地使用包loopMT的类?还有另外一种(更安全、更优雅)的方法来编写这个程序吗?我可以在多线程环境中使用System.out吗?

非常感谢你的建议

皮埃尔

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-01-28 09:54:21

正如当前编写的那样,loopMT没有等待提交的任务完成。

你有几个选择:

  • 调用awaitTermination()等待所有原始测试的完成,并将结果写入System.out,就像您当前所做的那样。
  • 将接口从Runnable更改为Callable<Boolean>Callable<Map.Entry<Long, Boolean>>并使用service.invokeAll() (然后您将立即获得返回的所有结果)。
  • 将结果存储在同步的Map中,并在所有原始测试完成后读取它
  • run方法将结果发送到BlockingQueueSynchronousQueue,并让loopMT方法循环从队列中获取结果并打印出来。这是我更喜欢的选择。
  • 通过CompletionService间接使用队列。
票数 1
EN

Stack Overflow用户

发布于 2010-01-28 09:57:17

由于System.outPrintStream的一个实例,所以它是线程安全的。因此,这是很好的训练例子。但是对于我来说,不同线程的输出似乎不是个好主意。最好有一个专用的输出线程来异步地接受输出请求。

也许,我更愿意按照finnw的建议实现Callable<Boolean>,否则,除了CPU消耗之外,我认为在IsPrime类中没有任何理由。

票数 2
EN

Stack Overflow用户

发布于 2010-01-28 09:54:53

由于此计算很可能是CPU绑定的,所以运行更多线程并不比您有CPU内核更有利。之后的额外线程只会增加开销。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2153439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档