我有一个创建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,但我只想知道系统如何处理这种冲突问题。)
答案 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
表示访问它的所有线程的值始终是最新的。