从所有线程更新共享变量

皮尤什·钱德拉

我是多线程的新手。我有一个 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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

等待所有线程

来自分类Dev

等待所有线程

来自分类Dev

Apache Beam:在实例中的所有线程之间共享资源

来自分类Dev

在终止时杀死所有线程

来自分类Dev

C#挂起所有线程

来自分类Dev

对于所有线程均适用

来自分类Dev

锁定所有线程的对象?

来自分类Dev

如何立即杀死所有线程

来自分类Dev

Jmeter:如何一次初始化映射并为线程组中的所有线程共享它

来自分类Dev

带有线程错误的 GUI 更新

来自分类Dev

C:文件范围变量是否可用于所有线程?

来自分类Dev

如何在所有线程之间同步变量的值?

来自分类Dev

Java-对可变对象的可变引用-将更新对象的字段对所有线程可见

来自分类Dev

锁定除python中的所有线程外的所有线程

来自分类Dev

挂起所有线程:MS使用线程警告-Android

来自分类Dev

线程障碍的问题-PulseAll无法到达所有线程

来自分类Dev

让主线程等待,直到所有线程结束

来自分类Dev

选择所有线程并按最新线程排序

来自分类Dev

空线程阻塞的所有线程被读取

来自分类Dev

如何使主线程等待所有线程完成

来自分类Dev

pthread_cond_wait(条件变量)如何只解除所有线程一次,而不是多次?

来自分类Dev

当所有线程未终止时,Valgrind输出

来自分类Dev

执行程序未运行所有线程。

来自分类Dev

为什么FUSE似乎锁定了所有线程?

来自分类Dev

ExecutorService的shutdown()不会等待所有线程完成

来自分类Dev

在所有线程中重新加载python模块

来自分类Dev

OpenMP:将所有线程分为不同的组

来自分类Dev

pthread-暂停/取消暂停所有线程

来自分类Dev

C#等待直到所有线程完成执行