java - 两个线程引用一个变量

标签 java multithreading java-threads

我正在运行下面的类(class)。

public class RunThreads implements Runnable {
    static int  i;
    public static void main(String[] args) {
        RunThreads job = new RunThreads();
        Thread alpha = new Thread(job);
        Thread beta = new Thread(job);
        alpha.setName("Alpha");
        beta.setName("beta");
        alpha.start();
        beta.start();
    }
    public void run(){
        for(;i<10;i++){
            System.out.println(Thread.currentThread().getName() + i);
        }
    }
}

我的输出是:

beta0
beta1
Alpha0
beta2
beta4
beta5
beta6
Alpha3
Alpha8
beta7
Alpha9

我知道每次执行时都会得到不同的输出。我的问题是,为什么对于 alphabeta 来说,输出的 i 值两次为 0 > 线程,即 Alpha0beta0

i 的值已被 beta 线程增加到 1。那么,alpha线程如何打印出Alpha0

我可能在这里遗漏了一些非常明显的东西。谢谢!

最佳答案

当您在没有同步等的情况下访问共享数据时,事情会很可怕:

  • 无法保证读取 i 的 Alpha 线程会看到 beta 线程的“最新”更新,反之亦然
  • 两个线程可以大致同时启动 i++...并且 i++ 基本上是:

    int tmp = i;
    tmp++;
    i = tmp;
    

    你很容易“失去”增量

如果你想使其线程安全,你应该使用 AtomicInteger相反:

import java.util.concurrent.atomic.AtomicInteger;

public class RunThreads implements Runnable {
    static AtomicInteger counter = new AtomicInteger();
    public static void main(String[] args) {
        RunThreads job = new RunThreads();
        Thread alpha = new Thread(job);
        Thread beta = new Thread(job);
        alpha.setName("Alpha");
        beta.setName("beta");
        alpha.start();
        beta.start();
    }
    public void run(){
        int local;
        while ((local = counter.getAndIncrement()) < 10) {
            System.out.println(Thread.currentThread().getName() + local);
        }
    }
}

您的输出可能仍然出现错误的顺序(因为 alpha 线程可能“开始”写入“Alpha0”,而 beta 线程“开始”写入“beta1”,但 beta 线程得到首先锁定控制台输出),但您只会看到每个计数一次。请注意,您必须使用 getAndIncrement() 的结果进行检查和打印 - 如果您在循环体中调用 counter.get(),您由于操作的交错,仍然可以看到重复项。

关于java - 两个线程引用一个变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42511469/

相关文章:

java - setTextSize 不适用于 Android 中的 AutofitTextView

java - Java 中的并行文件下载到 U 盘

multithreading - 调试一个线程会阻止其他线程?

java - 尝试在循环内找到两个数组列表的最小值

java - 将 com.itextpdf.text.Image 保存为图像文件

c - Massif 工具是否可以在多线程应用程序中正常工作?

c++ - 为什么执行矩阵乘法的两个进程并行运行比连续运行慢?

java - RequestFuture.get(long timeout, Timeunit unit) 不超时

java - 如何访问 ThreadPoolExecutor 中正在运行的线程?

java - 将工作线程与主线程一起使用会减少基于 Java 的智能设备的响应延迟或增加工作负载吗?