Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这两个并发实现中哪一个更好更快_Java_Concurrency_Java.util.concurrent - Fatal编程技术网

Java 这两个并发实现中哪一个更好更快

Java 这两个并发实现中哪一个更好更快,java,concurrency,java.util.concurrent,Java,Concurrency,Java.util.concurrent,我有两个并行生成素数的实现。核心代码取自Stackoverflow中的另一篇文章 我想知道这些实现中哪一个是首选的,为什么?还有,是否有更好更快的解决方案 实施1: import java.util.Scanner; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class Prime

我有两个并行生成素数的实现。核心代码取自Stackoverflow中的另一篇文章

我想知道这些实现中哪一个是首选的,为什么?还有,是否有更好更快的解决方案

实施1:

import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class PrimeThreads {

    private static int currentPrime = 0;

    public static void main(String[] args) {

        Object lock = new Object();

        Thread primerGenThread = new Thread(() -> {
            String threadName = Thread.currentThread().getName();
            System.out.println("Starting thread: " + threadName);
            int currentPrimeNo = 0;
            synchronized (lock) {
                try {
                    currentPrimeNo = generateNextPrime();
                } catch (InterruptedException e) {

                    e.printStackTrace();
                }
            }
            System.out.println("Prime Number Associated with this thread " + threadName + " is: " + currentPrimeNo);
            System.out.println("Completed thread: " + threadName);
        });

        System.out.println("****This is where the project starts*****");

        Scanner reader = new Scanner(System.in);
        System.out.print("Enter number of threads you want to create: ");
        int n = reader.nextInt();
        reader.close();

        ExecutorService executor = Executors.newFixedThreadPool(n);
        for(int i=1;i<=n; i++) {
            executor.submit(primerGenThread);
        }
        executor.shutdown();
        try {
            executor.awaitTermination(10, TimeUnit.MINUTES);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        System.out.println("****This is where the project ends*****");

    }

    private static int generateNextPrime() throws InterruptedException {

        long startTime = System.nanoTime();

        currentPrime++;
        if (currentPrime < 2) {
            currentPrime = 2;
            return currentPrime;
        }
        for (int i = 2; i < currentPrime; i++) {
            if (currentPrime % i == 0) {
                currentPrime++;
                i = 2;
            } else {
                continue;
            }
        }       

        long endTime = System.nanoTime();
        System.out.println("Time taken: " + (endTime - startTime) + " naoseconds.");
        return currentPrime;
    }

}
import java.util.Scanner;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.TimeUnit;
公共类素数线程{
私有静态int currentPrime=0;
公共静态void main(字符串[]args){
对象锁=新对象();
线程primerGenThread=新线程(()->{
字符串threadName=Thread.currentThread().getName();
System.out.println(“起始线程:“+threadName”);
int currentPrimeNo=0;
已同步(锁定){
试一试{
currentPrimeNo=generateNextPrime();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
System.out.println(“与此线程关联的素数”+threadName+”为:“+currentPrimeNo”);
System.out.println(“完成的线程:“+threadName”);
});
System.out.println(“****这是项目开始的地方*****”);
扫描仪阅读器=新扫描仪(System.in);
System.out.print(“输入要创建的线程数:”);
int n=reader.nextInt();
reader.close();
ExecutorService executor=Executors.newFixedThreadPool(n);
对于(int i=1;i System.out.println)(“与此线程关联的素数”
+Thread.currentThread().getName()+“是:“+currentPrime”);
}
executor.shutdown();
试一试{
执行人。等待终止(10,时间单位。分钟);
}捕捉(中断异常e1){
e1.printStackTrace();
}
System.out.println(“****这是项目结束的地方*****”);
}
私有静态int generateNextPrime()引发InterruptedException{
long startTime=System.nanoTime();
currentPrime++;
if(currentPrime<2){
currentPrime=2;
返回电流素数;
}
对于(int i=2;i
感谢您的建议和帮助

编辑: 还注意到,第二个实现并不保证每个线程都将获得一个新的素数。在这种情况下,有时多个线程获得相同的currentPrime变量值


谢谢。

这些实现之间的主要区别在于它们的执行方式

执行1基本上等于顺序执行。使用线程没有任何好处,因为如何使用同步块。 每个线程都会等待前一个线程完成,然后再生成下一个素数

您已经注意到,实现2多次计算相同的素数。这是因为没有同步。只有计数器
currentPrime
用于控制下一个线程中哪个数字应被视为prime

因此,两种实现都无法并行计算素数以产生可行的结果

想想日常生活。您可以使用一个值来确定它是否为素数。这个值应该是每个线程进行计算的输入。 现在唯一要考虑的是如何使这个值线程安全,以确保它只使用一次。 这可以通过使用原子变量来实现,例如
currentPrime

另一个改进是在
generateNextPrime()
方法之外增加
currentPrime
。此方法可以将该值作为参数。差不多

generateNextPrime(currentPrime.incrementAndGet());

你已经试过了吗?我只说过一句话。即使值currentPrime是每个线程的输入,多个线程产生相同素数的可能性也很大。当我尝试使用原子整数时。谢谢
generateNextPrime(currentPrime.incrementAndGet());