Java多线程访问同一个变量

时间:2013-09-21 12:40:41

标签: java asynchronous synchronized

我有一个创建2个线程的Java程序,在这2个线程中,他们试图将全局变量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,但我只想知道系统如何处理这种冲突问题。)

6 个答案:

答案 0 :(得分:3)

操作系统几乎没有参与:在线程运行时,分配给abc的内存受JVM运行程序的控制,因此它是你的程序控制。

当两个线程访问相同的内存位置时,最后一个写入器获胜。然而,哪个特定线程成为最后一个编写器是非确定性的,除非您使用同步。

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

要避免同步问题,您应该使用同步或其中一个java.util.concurrent.atomic类。

答案 1 :(得分:3)

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

我们假设abc原来是0。在你的两个线程分别将其更新为1和3之后,可以在三种状态下观察到abc:0,1或3.您得到的值不是确定性的,结果可能会因一次运行而异。

答案 2 :(得分:2)

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

某些环境实际上会阻止您这样做 - 称为线程安全。

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

它主要取决于哪个线程最后更新它的值。一个线程将首先获得CPU周期,然后再执行原子操作。

另外,我认为操作系统不会调度线程,因为在大多数操作系统中,它是负责它们的程序,并且没有像synchronizedize这样的显式调用,或者一个线程池模型然后我认为执行的顺序很难预测。它是一个非常依赖环境的东西。

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

  

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

结果将不具有确定性,因为该值将是最后写入的值。您无法保证结果。执行安排与任何其他执行一样。由于您的代码中不需要同步,因此JVM不会为您强制执行任何操作。

  

我知道应该使用Synchronize,但我只想自然地知道   系统将如何处理这种冲突问题。

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

答案 5 :(得分:1)

只需将volatile modificator添加到您的变量中,然后它将通过所有线程进行更新。阅读它的线程将获得它的实际价值。 volatile表示访问它的所有线程的值始终是最新的。