2013-09-21 27 views
0

我有创建2个线程,这两个线程内一个Java程序,他们要更新全局变量abc不同的价值,让我们说整数1和整数3.Java的多线程访问同一个变量

比方说,他们执行在同一时间码(在相同milisecond),例如:

public class MyThread implements Runnable{ 
    public void run(){ 
     while(true){ 
      if (currentTime == specificTime){ 
       abc = 1; //another thread update abc to 3 
      } 
     } 
    } 
} 

在这种情况下,我们怎么能确定变量abc的结果呢?我非常好奇操作系统如何安排执行?

(我知道应该同步使用,但我只是想知道自然的系统将如何处理这种冲突问题。)

+0

你应该阅读关于锁定。 http://msdn.microsoft.com/en-us/magazine/cc163744.aspx –

+4

@Aubin在java中写入和读取原语IS原子,只有'long'和'double'不是原子的。他的问题是阅读和写作不是原子操作。 –

回答

2

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

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

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

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

此外,我不认为操作系统会尽可能安排线程,因为在大多数操作系统中,它是负责它们的程序,并且没有显式调用(如同步)或线程池模型那么我认为执行的顺序很难预测。它是一个非常依赖环境的东西。

+0

完全同意! –

1

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

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

3

操作系统几乎没有涉及:在线程运行时,分配给abc的内存由运行程序的JVM控制,所以它是您的程序在控制中。

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

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

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

1

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

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

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

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

3

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

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

1

只需将volatile修饰符添加到您的变量中,然后它将通过所有线程进行修改。读线程会得到它的实际价值。 volatile表示对于访问它的所有线程,该值始终是最新的。