简体   繁体   English

Java多线程访问相同的变量

[英]Java multi-threading accessing same variable

I have a Java program which create 2 threads, inside these 2 threads, they are trying to update the global variable abc to different value, let's say integer 1 and integer 3. 我有一个Java程序,该程序创建2个线程,在这2个线程中,它们试图将全局变量abc更新为不同的值,例如整数1和整数3。

Let's say they execute the code at the same time (at same milisecond), for example: 假设他们在同一时间(同一毫秒)执行代码,例如:

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

In this case, how can we determine the result of the variable abc ? 在这种情况下,我们如何确定变量abc的结果? I am very curious how Operating System schedule the execution? 我很好奇操作系统如何安排执行时间?

(I know Synchronize should be used, but I just want to know naturally how the system will handle this kind of conflict problem.) (我知道应该使用同步,但是我只想自然地知道系统将如何处理这种冲突问题。)

The operating system has little involvement in this: at the time your threads are running, the memory allocated to abc is under control of JVM running your program, so it's your program that is in control. 操作系统对此几乎没有参与:在线程运行时,分配给abc的内存在运行程序的JVM的控制下,因此程序是受控制的。

When two threads access the same memory location, the last writer wins. 当两个线程访问相同的内存位置时,最后一个写入程序获胜。 Which particular thread gets to be the last writer, however, is non-deterministic, unless you use synchronization. 但是,除非您使用同步,否则哪个特定线程将成为最后一个写程序是不确定的。

Moreover, without you taking special care of accessing the shared data, one thread may not even see the results of the other thread writing to the abc location. 此外,如果您不特别注意访问共享数据,则一个线程甚至可能看不到另一线程写入abc位置的结果。

To avoid synchronization issues, you should use synchronization or one of the java.util.concurrent.atomic classes. 为避免同步问题,应使用同步或java.util.concurrent.atomic类之一。

From Java's perspective the situation is fairly simple if abc is not volatile or accessed with appropriate synchronisation. 从Java的角度来看,如果abc不是易失性的或通过适当的同步访问的,则情况相当简单。

Let's assume that abc is 0 originally. 假设abc最初是0。 After your two threads have updated it to respectively 1 and 3, abc could be observed in three states: 0, 1 or 3. Which value you get is not deterministic and the result may vary from one run to the other. 在两个线程分别将其更新为1和3之后,可以在三种状态下观察abc :0、1或3。获得的值不是确定性的,一次运行的结果可能会不同。

Depends on the operating system, running environment etc. 取决于操作系统,运行环境等。

Some environments will actually stop you from doing this - known as thread safety. 某些环境实际上会阻止您执行此操作-称为线程安全。

Otherwise the results are totally unpredictable which is why it is so dangerous to do this. 否则结果是完全不可预测的,这就是为什么这样做如此危险的原因。

It mainly just depends on which thread updated it last for what the value will be. 它主要取决于最后更新哪个线程的值。 One thread will get CPU cycles before the other to do the atomic operation first. 一个线程将在其他线程首先执行原子操作之前获得CPU周期。

Also, I don't think that operating systems go as far as to schedule threads because in most operating systems it is the program that is responsible for them, and without explicit calls like synchronise, or a threading pool model then I think the order of execution is pretty hard to predict. 另外,我不认为操作系统可以安排线程,因为在大多数操作系统中,是由程序负责它们,并且没有像同步之类的显式调用或线程池模型,所以我认为执行很难预测。 Its a very environment dependent thing. 它是非常依赖环境的。

From the system's perspective the result will depend on many software, hardware and run-time factors that cannot be known in advance. 从系统的角度来看,结果将取决于许多软件,硬件和运行时因素,而这些因素是无法事先知道的。 From this perspective there is no conflict nor a problem. 从这个角度看,没有冲突也没有问题。

From the programmer's perspective the result is not deterministic and therefore a problem/conflic. 从程序员的角度来看,结果不是确定性的,因此是一个问题/冲突。 The conflict needs to be resolved at design-time. 冲突需要在设计时解决。

In this case, how can we determine the result of the variable abc ? 在这种情况下,我们如何确定变量abc的结果? I am very curious how Operating System schedule the execution? 我很好奇操作系统如何安排执行时间?

The result will not be deterministic, as the value will be the last written one. 结果将不确定,因为该值将是最后写入的值。 You can not make any guarantee about the result. 您不能保证任何结果。 The execution is scheduled like any other one. 计划执行与其他任何执行一样。 As you demand no synchronization in your code the JVM will not enforce anything for you. 由于您不需要代码同步,因此JVM不会为您执行任何操作。

I know Synchronize should be used, but I just want to know naturally how the system will handle this kind of conflict problem. 我知道应该使用同步,但是我只想自然地知道系统将如何处理这种冲突问题。

Simple said: it wont, as for the system there is no conflict. 简单地说:它不会,因为系统没有冲突。 Only for you, the programmer, problems will occur, since you will eventually run into a data race and not deterministic behavior. 仅对于您(程序员)而言,问题就会发生,因为您最终将陷入数据争夺而不是确定性的行为。 It is completely up to you. 这完全取决于你。

just add volatile modificator to your variable, then it'll be udpated through all threads. 只需将volatile修饰符添加到您的变量中,即可在所有线程中进行修改。 And thread reading it will get it's actual value. 并且线程读取它会得到它的实际值。 volatile means that value will be always up to date for all threads accessing it. volatile意味着该值对于所有访问它的线程而言始终是最新的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM