开发者

java.util.concurrent : calculating primes

开发者 https://www.devze.com 2022-12-18 04:09 出处:网络
I\'m new to the package java.util.concurrent. I\'ve created the following program testing if a number is a prime using a multi and a monothreaded strategy.

I'm new to the package java.util.concurrent. I've created the following program testing if a number is a prime using a multi and a monothreaded strategy.

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.o开发者_C百科ut.println(""+n1+" >>> "+n2);   
        }
    }

for the method loopMT, is it the correct way to use the classes of the package java.util.concurrent ? Is there another, (safer, more elegant) way to write this program ? Can I use System.out in a multithreaded environement ?

Many thanks for your suggestions

Pierre


As System.out is an instance of PrintStream it is thread-safe. So it is fine for training examples. But generally output from different threads doesn't seem like a good idea to me. It's better to have dedicated output thread that accepts requests for output asynchronously.

Probably, I'd rather implemented Callable<Boolean> as finnw suggested, otherwise I see no reason in IsPrime class except of CPU consumption.


As it is currently written loopMT is not waiting for the submitted tasks to complete.

You have a few options:

  • Call awaitTermination() to wait for all primality tests to complete, writing the results to System.out as you are currently doing.
  • Change the interface from Runnable to Callable<Boolean> or maybe Callable<Map.Entry<Long, Boolean>> and use service.invokeAll() (then you will get all results returned at once.)
  • Store the results in a synchronized Map and read it when all the primality tests have completed
  • Have the run method send the results to a BlockingQueue or SynchronousQueue and have the loopMT method loop fetching the results from the queue and printing them. This is the option I would prefer.
  • Use a queue indirectly, via a CompletionService.


Since this calculation is likely CPU bound, there is no advantage to running more threads than you have CPU cores. Extra threads after that only add to overhead.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号