!=检查线程是否安全? [英] Is the != check thread safe?

查看:186
本文介绍了!=检查线程是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道复合操作(例如 i ++ )不是线程安全的,因为它们涉及多个操作。

I know that compound operations such as i++ are not thread safe as they involve multiple operations.

但是检查引用本身是否为线程安全操作?

But is checking the reference with itself a thread safe operation?

a != a //is this thread-safe

我试图对此进行编程并使用多个线程但它并没有失败。我想我无法在我的机器上模拟比赛。

I tried to program this and use multiple threads but it didn't fail. I guess I could not simulate race on my machine.

public class TestThreadSafety {
    private Object a = new Object();

    public static void main(String[] args) {

        final TestThreadSafety instance = new TestThreadSafety();

        Thread testingReferenceThread = new Thread(new Runnable() {

            @Override
            public void run() {
                long countOfIterations = 0L;
                while(true){
                    boolean flag = instance.a != instance.a;
                    if(flag)
                        System.out.println(countOfIterations + ":" + flag);

                    countOfIterations++;
                }
            }
        });

        Thread updatingReferenceThread = new Thread(new Runnable() {

            @Override
            public void run() {
                while(true){
                    instance.a = new Object();
                }
            }
        });

        testingReferenceThread.start();
        updatingReferenceThread.start();
    }

}

这是我的程序用来测试线程安全性。

This is the program that I am using to test the thread-safety.

当我的程序在一些迭代之间开始时,我得到了输出标志值,这意味着对同一引用的引用!= 检查失败。但经过一些迭代后,输出变为常量值 false ,然后长时间执行程序不会生成单个 true 输出。

As my program starts between some iterations I get the output flag value, which means that the reference != check fails on the same reference. BUT after some iterations the output becomes constant value false and then executing the program for a long long time does not generate a single true output.

正如输出建议在一些n(非固定)迭代之后,输出似乎是常数值并且不会改变。

As the output suggests after some n (not fixed) iterations the output seems to be constant value and does not change.

输出:

对于某些迭代:

1494:true
1495:true
1496:true
19970:true
19972:true
19974:true
//after this there is not a single instance when the condition becomes true


推荐答案

在没有同步的情况下,此代码

In the absence of synchronization this code

Object a;

public boolean test() {
    return a != a;
}

可能产生 true 。这是的字节码test()

    ALOAD 0
    GETFIELD test/Test1.a : Ljava/lang/Object;
    ALOAD 0
    GETFIELD test/Test1.a : Ljava/lang/Object;
    IF_ACMPEQ L1
...

我们可以看到它加载字段 a 到本地变量两次,这是一个非原子操作,如果 a 之间被另一个线程比较改变可能会产生

as we can see it loads field a to local vars twice, it's a non-atomic operation, if a was changed in between by another thread comparison may produce false.

此外,内存可见性问题与此相关,无法保证由另一个线程对 a 所做的更改对当前线程可见。

Also, memory visibility problem is relevant here, there is no guarantee that changes to a made by another thread will be visible to the current thread.

这篇关于!=检查线程是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆