Java多线程访问同一变量

Java多线程访问同一变量,java,asynchronous,synchronized,Java,Asynchronous,Synchronized,我有一个Java程序,它创建了两个线程,在这两个线程中,它们试图将全局变量abc更新为不同的值,比如整数1和整数3 假设他们在同一时间以同一毫秒执行代码,例如: public class MyThread implements Runnable{ public void run(){ while(true){ if (currentTime == specificTime){ abc = 1; //another t

我有一个Java程序,它创建了两个线程,在这两个线程中,它们试图将全局变量abc更新为不同的值,比如整数1和整数3

假设他们在同一时间以同一毫秒执行代码,例如:

public class MyThread implements Runnable{
    public void run(){
        while(true){
            if (currentTime == specificTime){
                abc = 1; //another thread update abc to 3
            }
        }
    }
} 
在这种情况下,我们如何确定变量abc的结果?我很好奇操作系统是如何安排执行的


我知道应该使用Synchronize,但我只是想知道系统将如何处理此类冲突问题。

取决于操作系统、运行环境等

有些环境实际上会阻止您这样做,称为线程安全

否则,结果是完全不可预测的,这就是为什么这样做是如此危险

这主要取决于哪个线程最后更新了它的值。一个线程将在另一个线程之前获得CPU周期,以便首先执行原子操作


另外,我不认为操作系统会对线程进行调度,因为在大多数操作系统中,是程序负责线程调度,如果没有诸如synchronise或线程池模型之类的显式调用,那么我认为执行顺序很难预测。这是一件非常依赖于环境的事情。

从系统的角度来看,结果将取决于许多无法事先知道的软件、硬件和运行时因素。从这个角度来看,既没有冲突,也没有问题


从程序员的角度来看,结果不是确定性的,因此是一个问题/冲突。冲突需要在设计时解决

操作系统与此无关:在线程运行时,分配给abc的内存由运行程序的JVM控制,因此由程序控制

当两个线程访问同一内存位置时,最后一个写入程序获胜。但是,除非使用同步,否则哪个特定线程将成为最后一个写入程序是不确定的

此外,如果不特别注意访问共享数据,一个线程甚至可能看不到另一个线程写入abc位置的结果

为了避免同步问题,应该使用同步或java.util.concurrent.atomic类之一

在这种情况下,我们如何确定变量abc的结果?我 我很好奇操作系统是如何安排执行的

结果将不是确定性的,因为该值将是最后写入的值。你不能对结果作任何保证。执行计划与其他任何一个一样。由于您不需要在代码中进行同步,JVM将不会为您强制执行任何内容

我知道应该使用同步,但我只是想知道 系统将如何处理此类冲突问题


Simple说:不会的,因为系统没有冲突。只有程序员才会出现问题,因为您最终会遇到数据竞争,而不是确定性行为。这完全取决于您。

从Java的角度来看,如果abc不是易变的或通过适当的同步进行访问,情况就相当简单


让我们假设abc最初是0。在您的两个线程分别将其更新为1和3之后,可以观察到abc处于三种状态:0、1或3。您得到的值是不确定的,结果可能因运行而异。

只需将volatile modificator添加到您的变量中,就可以在所有线程中使用它。线程读取它将得到它的实际值。volatile意味着对于所有访问该值的线程,该值将始终是最新的。

您应该了解锁定@Aubin在java中编写和读取原语是原子的,只有long和double不是原子的。他的问题是先读后写不是原子操作。