等待ThreadPool完成并启动SingleThread

时间:2018-04-15 00:38:27

标签: java multithreading threadpool

我正在尝试通过使用10个线程的ThreadPool和第二次运行来检查一个数字是否为素数,我只检查一个线程。这里的想法是我还检查使用10个线程的ThreadPool和1个单线程之间的速度差异。

我的问题是,在启动单线程操作之前,我有点担心如何等待PoolThread完成。

我尝试在PrimeTask类中同步一个函数,但我仍然对线程很新,并且不确定为什么我没有得到所需的行为。我很想知道我缺少什么以及为什么。

import java.util.concurrent.*;

public class PrimeChecker
{
    private static ExecutorService executor;
    private final static long number = 9223372036854775783L;
    private final static int numberOfThreads = 10;
    private static long startValues;
    private static long endValues;
    static long startTime;
    static long endTime;

    private PrimeChecker() { };

    public static void main(String[] args)
    {
        init();
        runThreads();
    }

    private static void init()
    {
        startValues = 3L;
        endValues = (long) Math.sqrt(number) / 10L;
    }

    private static void runThreads()
    {
        startTime = System.currentTimeMillis();
        executor = Executors.newFixedThreadPool(numberOfThreads);
        System.out.print("Chekcing if " + number + " is a prime number, multithreaded.\n");
        for (int x = 1; x < 10; x++)
        {
            executor.execute(new PrimeTask(number, startValues, endValues));
            startValues = ((endValues / 10) * x);
            endValues = ((endValues / 10) * (x + 1));
        }
        executor.shutdown();

        singlethreadedPrime();
    }

    private static void singlethreadedPrime()
    {
        startTime = System.currentTimeMillis();
        executor = Executors.newFixedThreadPool(1);
        System.out.println("Chekcing if " + number + " is a prime number, singlethreaded.");
        executor.execute(new PrimeTask(number, startValues, endValues));
        executor.shutdown();
    }

    static class PrimeTask implements Runnable
    {
        private long number;
        private long startValue;
        private long endValue;

        public PrimeTask(long Numb, long startVal, long endVal)
        {
            number = Numb;
            startValue = startVal;
            endValue = endVal;
        }


        @Override
        public void run() 
        {
            if (isPrime(number, startValue, endValue))
            {
                endTime = System.currentTimeMillis();
                System.out.printf("Time millisecond: %d\n", (endTime - startTime));
                System.out.println(number + " is Prime");
            }
            else
            {
                endTime = System.currentTimeMillis();
                System.out.printf("Time millisecond: %d\n" + (endTime - startTime));
                System.out.println(number + " not Prime");  
            }
        }

        public static synchronized boolean isPrime(long n, long sV, long eV)
        {
            if((n % 2) == 0)
            {
                return false; // not prime
            }
            else
            {
                for(long i = sV; i*i <= eV; i+=2) 
                {
                    if(n%i==0)
                        return false; // not prime
                }
                return true; // prime
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您使用了“执行”,但您似乎想等待结果。 所以你可以使用submit()返回一个未来。 因此,您可以等待future.get()(阻塞)。

只有一个未来,这是微不足道的。对于10个期货,你会在一个列表中堆积期货,然后当所有提交时,在每个期货上调用.get()相当简单。第一个将花费一些时间,但后者将更快,或者甚至不在.get()中阻止,如果已经完成。 (当然你可以为future.isDone()进行民意调查,但这很浪费)

您使用的executor.shutdown()应该等待所有正在进行的任务完成,但问题可能是它们并非全部正在进行中,而只是排队。

最后,您可以使用CountDownLatch等待所有完成。将倒计时锁存器传递给所有任务。