我是多线程的新手。我有一个 volatile 变量 currentPrimeNo ,它将打印在每个新线程的 run 方法中实现的下一个素数。但是每次我将每个线程的 currentPrimeNo 都设置为 0 时。我应该如何保持全局变量 currentPrimeNo 更新?
public class Processor implements Runnable {
private int id;
private static volatile int currentPrimeNo = 0;
public Processor(int id) {
this.id = id;
}
@Override
public void run() {
System.out.println("Starting process id: " + id);
currentPrimeNo = Utils.generateNextPrime(currentPrimeNo);
System.out.println("Prime Number Associated with this thread is: " + currentPrimeNo);
System.out.println("Completed process id: " + id);
}
}
主要类是:
public class MainClass {
@SuppressWarnings("resource")
public static void main(String[] args) {
System.out.println("****This is where the project starts*****");
Scanner reader = new Scanner(System.in);
System.out.print("Enter number of processes you want to create: ");
int n = reader.nextInt();
ExecutorService executor = Executors.newFixedThreadPool(n);
for(int i=1;i<=n; i++) {
executor.submit(new Processor(i));
}
executor.shutdown();
try {
executor.awaitTermination(10, TimeUnit.MINUTES);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("****This is where the project ends*****");
}
}
下面是 Util 类的 generateNextPrime 方法:
public synchronized static int generateNextPrime(int currentPrime) {
int nextPrime = 2;
if (currentPrime <= 1) {
return nextPrime;
} else {
for (int i = currentPrime + 1;; i++) {
boolean notPrime = false;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
notPrime = true;
break;
}
}
if (notPrime == false) {
return i;
}
}
}
}
以下是我得到的输出:
****这是项目开始的地方****
输入要创建的进程数:4
启动进程 ID:2
启动进程 ID:3
启动进程 ID:1
启动进程 ID:4
与此线程相关的质数是:2
与此线程相关的质数是:2
已完成的进程 ID:4
已完成的进程 ID:1
与此线程相关的质数是:2
已完成的进程 ID:2
与此线程相关的质数是:2
已完成的进程 ID:3
****项目到此结束*****
由于您尚未在generateNextPrime
此处共享代码,因此很难指出代码究竟出在哪里。
有一个与此相关的固有问题。
添加 Util.generateNextPrime() 后进行编辑。
当我们使用volatile
关键字时,所有线程都会看到变量的当前值而不是缓存值。但是在您的代码中,volatile
变量是在Runnable
实现中定义的。因此,它不会为此目的服务。确实,run
方法调用generateNextPrime
并传递volatile
变量,但被调用的方法实际看到和处理的是变量的副本,而不是确切的变量(阅读更多关于按值传递与按引用传递将有助于更好地理解这一点) . 这里的目标是有一个变量,它的值应该generateNextPrime
通过每个线程在运行时完成的调用来改变。
我将currentPrimeNo
定义移到Util
类中,以便所有线程只能看到一个变量(而不是它的副本),而且volatile
变量的实时值也是如此。generateNextPrime
为了紧凑起见,方法() 也做了一些改动。输出不一定需要按照相同的顺序,因为您将不知道工作线程的调用顺序。
这是代码:
public class Processor implements Runnable {
private int id;
public Processor(int id) {
this.id = id;
}
@Override
public void run() {
System.out.println("Starting process id: " + id);
int currentPrimeNo = Utils.generateNextPrime();
System.out.println("Prime Number Associated with this thread " + id +" is: " + currentPrimeNo);
System.out.println("Completed process id: " + id);
}
}
public class Utils {
private static volatile int currentPrime = 0;
public static synchronized int generateNextPrime(){
currentPrime++;
if(currentPrime < 2){
currentPrime = 2;
return currentPrime;
}
for (int i = 2; i <currentPrime; i++) {
if(currentPrime%i == 0) {
currentPrime++;
i=2;
} else{
continue;
}
}
return currentPrime;
}
}
基准测试时看到的输出
示例 1:
****This is where the project starts*****
Enter number of processes you want to create: 4
Starting process id: 3
Starting process id: 1
Starting process id: 2
Starting process id: 4
Prime Number Associated with this thread 3 is: 2
Prime Number Associated with this thread 1 is: 7
Completed process id: 1
Prime Number Associated with this thread 2 is: 3
Completed process id: 2
Prime Number Associated with this thread 4 is: 5
Completed process id: 3
Completed process id: 4
****This is where the project ends*****
示例 2:
****This is where the project starts*****
Enter number of processes you want to create: 6
Starting process id: 5
Starting process id: 1
Starting process id: 3
Starting process id: 2
Starting process id: 4
Prime Number Associated with this thread 2 is: 7
Prime Number Associated with this thread 4 is: 11
Completed process id: 4
Prime Number Associated with this thread 1 is: 3
Completed process id: 1
Prime Number Associated with this thread 5 is: 5
Completed process id: 5
Prime Number Associated with this thread 3 is: 2
Starting process id: 6
Completed process id: 2
Prime Number Associated with this thread 6 is: 13
Completed process id: 6
Completed process id: 3
****This is where the project ends*****
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句