Race Condition vs Data Race

2020-11-17  本文已影响0人  From64KB

Race Condition(竞争条件):多个线程访问共享的数据。共享数据最终的结果取决于线程的执行顺序。
Data Race(数据竞争):多个线程访问未经同步访问控制的共享数据,并且至少一个线程是写数据。

解释有点抽象,举个例子。有两个线程分别对共享的变量i赋值,线程1赋值1,线程2赋值2,那么线程1和线程2即构成Race Condition。而这两个线程会导致Data Race。语言表达还是抽象,见代码:

    private int x = 0;

    public void test() {

        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                x = 1;
            }
        };

        Runnable runnable1 = new Runnable() {

            @Override
            public void run() {
                x = 2;
            }
        };

        new Thread(runnable).start();
        new Thread(runnable1).start();

    }

由于JVM对int 类型的x赋值操作是原子性的,所以最终的结果取决于线程的访问顺序。
如果x的类型不是int而是long或者double呢?情况就变得复杂起来。long或者double在Java中占据64个bit,Java对于这两个数据类型的赋值操作并没有原子性保证。所以对于long或者double可以看成两个32bit的数据组合起来,那么就会存在某个线程更新一个32位,另一个线程更新另一个32位数据。或者一个线程在更新其中的一个32位,另一个线程在读取这个64位的bit。这样都会导致的结果就是无法预期的。

对于开发中的用的ConcurrentHashMap也要注意使用的方法,不是使用了ConcurrentHashMap就可以避免并发问题。仔细看下面的代码:

        ConcurrentHashMap<String, String> stringStringConcurrentHashMap = new ConcurrentHashMap<>();

        //方法1
        if (!stringStringConcurrentHashMap.containsKey("1")) {
            stringStringConcurrentHashMap.put("1", "1");
        }

        //方法2
        stringStringConcurrentHashMap.putIfAbsent("1", "1");

上面的方法1和方法2中,只有方法2能在多线程情况下工作正常。

上一篇下一篇

猜你喜欢

热点阅读