java - 在java中无需同步即可在多个线程之间共享和更新变量

标签 java multithreading

我正在尝试使用多线程在java中模拟100 m运行比赛程序。在这次尝试中,我创建了一个原子整数变量,它应该对所有线程都是通用的。每个线程超过 100 后,这个变量应该增加 1。不幸的是,结果并不符合预期。这是我在程序中的尝试。

    package running;
    import java.util.concurrent.atomic.*;
    public class Employee implements Runnable{
    AtomicInteger j = new AtomicInteger();

public void run() {

for(int i=1;i<=100;i++){
        System.out.println(Thread.currentThread().getName()+" " + i);
        try {
             Thread.sleep(100);
        } 
        catch (InterruptedException e) {
             e.printStackTrace();
        }
        if(i==100)
        {
             System.out.println(Thread.currentThread().getName()+" is in "+j.incrementAndGet()+" place");

        }
}
} 

public static void main(String []args) throws Exception{
Employee e= new Employee();
Thread a= new Thread(e,"First");
Thread b= new Thread(e,"Second");
Thread c= new Thread(e,"Third");
Thread d= new Thread(e,"Fourth");
Thread f= new Thread(e,"Fifth");
a.start();
b.start();
c.start();
d.start();
f.start();

}
}

为了以易于理解的方式演示我的问题,我添加了一条打印语句来检查代码中线程的运行情况。这是输出的最后 10 行。

Second 100
Fourth 100
Third 100
Fifth 100
First 100
Fourth is in 3 place
Third is in 1 place
Second is in 2 place
Fifth is in 4 place
First is in 5 place

最佳答案

我没有看到意外的结果。当我运行你的代码时,我得到:

First is in 1 place
Third is in 3 place
Second is in 4 place
Fifth is in 2 place
Fourth is in 5 place

如果我再次运行代码,我会得到:

First is in 1 place
Second is in 2 place
Fifth is in 4 place
Fourth is in 3 place
Third is in 5 place

正如预期的那样,结果并不总是相同。并且 AtomicInteger 不会丢失任何更新。

如果希望结果按顺序显示,需要同步注册结果的部分代码。 (以确保第一个达到 100 的线程将在下一个线程达到 100 之前写入该信息)例如,请参见以下内容:

import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;

public class Employee implements Runnable {
    private static AtomicInteger j = new AtomicInteger();
    private static Queue<String> queue = new ArrayDeque<>();

    public static void main(String[] args) throws Exception {
        Employee e = new Employee();
        Thread a = new Thread(e, "First");
        Thread b = new Thread(e, "Second");
        Thread c = new Thread(e, "Third");
        Thread d = new Thread(e, "Fourth");
        Thread f = new Thread(e, "Fifth");
        a.start();
        b.start();
        c.start();
        d.start();
        f.start();

        a.join();
        b.join();
        c.join();
        d.join();
        f.join();

        while (queue.size() > 0) {
            System.out.println(queue.remove());
        }

    }

    public void run() {

        for (int i = 1; i <= 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (queue) {
                if (i == 100) {
                    queue.add(Thread.currentThread().getName() + " is in " + j.incrementAndGet() + " place");
                }
            }
        }
    }
}

关于java - 在java中无需同步即可在多个线程之间共享和更新变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44645415/

相关文章:

java - Ruby setter 方法语法 method=(value) - 与 Java 的比较

Java迭代读取和解析

c++ - 浏览器中的多线程 WebAssembly 比单线程慢,为什么?

c# - 当我引发事件时,它始终为null

java - 以下两种创建可执行 JAR 的方法有什么区别?

java - 万磁王 : Adding configurable product to cart fails : Please specify the product's option(s)

java - 使用类型变量泛型调用方法

java - Java中的虚假唤醒真的发生了吗?

python - 在多线程python中查找cpu-hogging插件

C++11线程等待