Java 这两个并发实现中哪一个更好更快
我有两个并行生成素数的实现。核心代码取自Stackoverflow中的另一篇文章 我想知道这些实现中哪一个是首选的,为什么?还有,是否有更好更快的解决方案 实施1: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
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());