JAVA 并发相关总结

简介

自从JAVA 创建以来,java 就支持类似锁与线程的并发操作。本篇内容主要帮助JAVA 开发者理解和应用JAVA 的核心并发概念 以及如何应用。

概念

概念介绍
原子性  一个原子操作就是要么全部成功,要么全部失败 
可见性  可见性是指 一个线程是否可以看到另一个线程的修改    

 

 

 

 

表 1并发概念

 

条件竞争

竞争产生的条件是当一个以上线程对同一个共享对象发生一系列操作, 并且会根据不同线程的执行顺序不同产生不同的结果. 下面的代码就不是线程安全的 value 值会被初始化多次, 因为执行顺序 check-then-act ( 检测是否为 null, 然后进行初始化) 导致懒加载的操作并不是原子性的:

 
class Lazy <T> {
  private volatile T value;
  T get() {
    if (value == null)
      value = initialize();
    return value;
  }
}

具体原因:... //todo

数据竞争

一个数据竞争产生的原因是 当超过两个线程尝试操作相同的 非 final 操作符定义的 变量并且没有使用synchronize 做线程同步的时候 。没有采用线程同步将会导致线程间的操作可见性,  产生的读取旧数据的情况 , 将会导致诸如无限循环、数据结构冲突、计算错误等情况 。下面的代码将会产生无限循环 ,因为读线程无法观察到 写线程的修改 :

 

class Waiter implements Runnable {
    private boolean shouldFinish;
    void finish() {
        shouldFinish = true;
        System.out.printf("should finish");
    }
    public void run() {
        long iteration = 0;
        while (!shouldFinish) {
            iteration++;
        }
        System.out.println("Finished after: " + iteration);
    }
}
class DataRace {
    public static void main(String[] args) throws InterruptedException {
        Waiter waiter = new Waiter();
        Thread waiterThread = new Thread(waiter);
        waiterThread.start();
        Thread.sleep(2000);
        waiter.finish();
        waiterThread.join();

    }
}

 


Java 内存模型: happens-before 关系

JAVA的内存模型或者说是读写操作,以及monitor的synchronize 操作 都是通称之为  happens-before relationship 进行排序的 .,

HAPPENS-BEFORE RELATIONSHIPS 拥有下列属性:
  •  Thread#start 发生在当前线程的所有操作之前.
  • 释放 monitor 发生在所有随后的试图获取这个 monitor 之前 .
  • 对一个 volatile 标记的变量的写操作发生在这个变量的所有读操作之前.
  • final 变量的初始化在所有引用的对象之前.
  • Thread#join 发生在当前线程的所有操作之后 .

 

 

 

 

 

 

 

 

posted @ 2020-02-03 21:36  ﹏Sakura  阅读(225)  评论(0编辑  收藏  举报