0%

前面的重要问题提炼

2018年7月7日 下午4:23

慕课网实战·高并发探索(三):线程安全性-原子性-CAS(CAS的ABA问题) - CSDN博客

  1. 什么是CAS?
  2. 为什么有了AtomicLong还要新增一个LongAdder呢?
    1. CAS底层实现是在一个死循环中不断地尝试修改目标值,直到修改成功。如果竞争不激烈的时候,修改成功率很高,否则失败率很高。在失败的时候,这些重复的原子性操作会耗费性能。
  3. LongAdder类的实现原理?
  4. AtomicBoolean中的compareAndSet方法作用?
    1. 这个方法可以做到的是控制一个boolean变量在一件事情执行之前为false,事情执行之后变为true。
    2. 或者也可以理解为可以控制某一件事只让一个线程执行,并仅能执行一次
      1
      2
      3
      if (isHappened.compareAndSet(false, true)) {//控制某有一段代码只执行一次
      log.info("execute");
      }
  5. AtomicIntegerFieldUpdater类的用途?
    1. 这个类的核心作用是要更新一个指定的类的某一个字段的值
    2. 并且这个字段一定要用volatile修饰同时还不能是static的。
  6. 什么是ABA问题?
    1. CAS操作的时候,其他线程将变量的值A改成了B,但是随后又改成了A,本线程在CAS方法中使用期望值A与当前变量进行比较的时候,发现变量的值未发生改变,于是CAS就将变量的值进行了交换操作。但是实际上变量的值已经被其他的变量改变过,这与设计思想是不符合的。
  7. AtomicStampReference的处理思想?
    1. 每次变量更新的时候,将变量的版本号+1,之前的ABA问题中,变量经过两次操作以后,变量的版本号就会由1变成3,也就是说只要线程对变量进行过操作,变量的版本号就会发生更改。
    2. 从而解决了ABA问题。
  8. 使用synchronized之后不同对象之间操作是互不补影响?
    1. 当synchronized修饰静态方法和类时,作用的对象是这个类的所有对象。
    2. 也就是说:这个类的所有实例是不能争抢的,必须一个个按顺序来。

慕课网实战·高并发探索(四):线程安全性-可见性-有序性 - CSDN博客

  1. 线程可见性的定义?
    1. 一个线程对主内存的修改可以及时的被其他线程观察到
  2. 导致共享变量在线程间不可见的原因?
    1. 线程交叉执行
    2. 重排序结合线程交叉执行
    3. 共享变量更新后的值没有在工作内存与主存间及时更新
  3. JMM关于synchronized的两条规定?
    1. 线程解锁前,必须把共享变量的最新值刷新到主内存
    2. 线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值(注意:加锁与解锁是同一把锁)
  4. Volatile的作用?
    1. 对volatile变量写操作时,会在写操作加入一条store屏障指令,将本地内存中的共享变量值刷新到主内存。
    2. 对volatile变量读操作时,会在读操作加入一条load屏障指令,从主内存中读取共享变量。
    3. 方式重排序
  5. Volatitle可以解决并发问题吗?
    1. volatile不会让你的程序变得更好,仅仅是通过防止指令重排,以免让程序因为重排序变得更坏。
    2. 所以,它不可以直接解决并发问题。
  6. volatile适合做什么呢?
    1. 比较适合做状态标记量(不会涉及到多线程同时读写的操作)

慕课网实战·高并发探索(六):不可变对象 -final -ImmutableX -unmodifiableX - CSDN博客

  1. 一个不可变对象需要满足的条件?
    1. 对象创建一个其状态不能修改
    2. 对象所有域都是final类型
    3. 对象是正确创建的(在对象创建期间,this引用没有逸出)
  2. 创建一个不可变对象的方法?
    1. 类声明为final,这样它就不能被继承
    2. 将所有的成员声明为私有的,这样就不允许直接访问这些成员。
    3. 对变量不提供set方法,将所有可变的成员声明为final,这样就只能赋值一次。通过构造器初始化所有成员进行深度拷贝。
    4. get方法中不直接返回对象的本身,而是克隆对象,返回对象的拷贝。
  3. unmodifiable相关类的实现原理是什么呢?

慕课网实战·高并发探索(七):线程封闭 - ThreadLocal - CSDN博客

  1. 什么是线程封闭
    1. 它其实就是把对象封装到一个线程里,只有一个线程能看到这个对象
  2. 堆栈封闭
    1. 就是将变量尽量放在方法中,而不是全局变量
  3. ThreadLocal线程封闭?
    1. 其实ThreadLocal内部维护了一个map,map的key是每个线程的名称,而map的value就是我们要封闭的对象
    2. ThreadLocal就像一个安全屋一样,可以保护放入的线程对象只归自己(当前线程)所有。
    3. 多个线程共有一个ThreadLocal,ThreadLocal会自动的分辨出当前线程是谁,以及对应的对象
    4. ThreadLocal用于保存某个线程共享变量:对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不会影响其他线程的变量。
  4. 工作内存的拷贝 与 并发问题的关系?
    1. 由于工作内存的拷贝,避免并发问题——实例:堆栈封闭
    2. 由于工作内存的拷贝,引起并发问题——实例:两个线程操作同一个全局变量

慕课网实战·高并发探索(八):线程不安全类、同步容器 - CSDN博客

  1. Vector也不是完全的线程安全的?
    1. synchronized关键字可以保证同一时间只有一个线程执行该方法,但是多个线程同时分别执行remove、add、get操作的时候就无法控制了。
  2. 同步容器和并发容器的区别?
    1. 同步容器将所有对容器的访问都串行化—每次只能有一个线程能访问它,以实现他们的线程安全性,这种方法的代价是严重降低并发性,当多个线程竞争访问容器的锁时,吞吐量将会严重减低。
    2. 并发容器:针对多个线程设计的,用并发容器来代替同步容器,可以极大地提高伸缩性并降低风险。
    3. 并发容器使用了与同步容器完全不同的加锁策略来提供更高的并发性和伸缩性,例如在ConcurrentHashMap中采用了一种粒度更细的加锁机制,可以称为分段锁,在这种锁机制下,允许任意数量的读线程并发地访问map,并且执行读操作的线程和写操作的线程也可以并发的访问map,同时允许一定数量的写操作线程并发地修改map,所以它可以在并发环境下实现更高的吞吐量。
    4. 同步容器和并发容器的区别 - CSDN博客
      1. 这个里面有具体的代码例子,来说明同步容器的缺点,以及使用方法。
      2. 同步容器也会线程不安全
    5. Java并发——同步容器与并发容器 - LaplaceDemon - 博客园
      1. 这个里面讲的并发容器种类非常多。