线程安全

三个核心概念
  1. 原子性
  2. 可见性
  3. 顺序性
怎么保证原子性
  1. synchronized
  2. cas。利用了CPU级别的CAS指令,由于是CPU级别的指令,其开销比需要操作系统参与的锁的开销小。

前两种方法原理一样,通过锁来实现资源的排它性。
使用锁,可以保证同一时间只有一个线程能拿到锁,也就保证了同一时间只有一个线程能执行申请锁和释放锁之间的代码。

public void testLock () {
  lock.lock();
  try{
    int j = i;
    i = j + 1;
  } finally {
    lock.unlock();
  }
}

使用非静态同步方法时,锁住的是当前实例;使用静态同步方法时,锁住的是该类的Class对象;使用静态代码块时,锁住的是synchronized关键字后面括号内的对象。

public void testLock () {
  synchronized (anyObject){
    int j = i;
    i = j + 1;
  }
}

怎么保证可见性

volatile关键字可以保证可见性。当使用volatile修饰某个变量时,它会保证对该变量的修改会立即被更新到内存中,并且将其它缓存中对该变量的缓存设置成无效

怎么保证顺序性

jvm有一些隐式的原则保证顺序。 happens-before原则(先行发生原则)

  1. 传递规则:如果操作1在操作2前面,而操作2在操作3前面,则操作1肯定会在操作3前发生。
  2. 锁定规则:一个unlock操作肯定会在后面对同一个锁的lock操作前发生。
  3. volatile变量规则:对一个被volatile修饰的写操作先发生于后面对该变量的读操作。
  4. 程序次序规则:一个线程内,按照代码顺序执行
  5. 线程启动规则:Thread对象的start()方法先发生于此线程的其它动作
  6. 线程终结原则:线程的终止检测后发生于线程中其它的所有操作
  7. 线程中断规则: 对线程interrupt()方法的调用先发生于对该中断异常的获取
  8. 对象终结规则:一个对象构造先于它的finalize发生
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容