线程安全及相关

  • 什么是线程安全
    堆内存中的数据由于可以被任何线程所访问,在没有限制的情况下存在被意外修改的风险。即堆内存空间在没有保护机制的情况下,对多线程来说是不安全的,因为放进去的数据可能被别的线程破坏。
    如果代码所在的进程中有多个线程在同时运行,而这些线程可能会同时执行这段代码,如果多线程运行的结果和单线程运行的结果是一样的,而且其他变量的值和预期也是一样的,就是线程安全的。
    编程新说:什么是线程安全

  • 怎样实现线程安全
    一般来说常见的用于保证线程安全的方式有两种

    1. synchronized
      synchronized关键字以及和 ReenTrantLock 的对比
    2. lock(ReenTrantLock )
      ReenTrantLock 为Lock的子类
      private Lock lock = new ReentrantLock();
       private void method(Thread thread){
         lock.lock(); // 获取锁对象
         try {
           System.out.println("线程名:"+thread.getName() + "获得了锁");
         // Thread.sleep(2000);
         }catch(Exception e){
           e.printStackTrace();
         } finally {
         System.out.println("线程名:"+thread.getName() + "释放了锁");
         lock.unlock(); // 释放锁对象
      }
      }
      

    5个步骤,教你瞬间明白线程和线程安全

  • synchronized与ReenTrantLock的区别
    synchronized关键字以及和 ReenTrantLock 的对比

  • synchronized关键字底层原理
    在Java中,每个对象里面隐式的存在一个叫monitor(对象监视器)的对象 。
    当monitor对象被线程持有时,Monitor对象中的count就会进行+1,当线程释放monitor对象时,count又会进行-1操作。用count来表示monitor对象是否被持有。
    1)monitorenter: monitorenter指令表示获取锁对象的monitor对象,这是monitor对象中的count并会加+1,如果monitor已经被其他线程所获取,该线程会被阻塞住,直到count=0,再重新尝试获取monitor对象

(2)monitorexit: monitorexit与monitorenter是相对的指令,表示进入和退出。执行monitorexit指令表示该线程释放锁对象的monitor对象,这时monitor对象的count便会-1变成0,其他被阻塞的线程可以重新尝试获取锁对象的monitor对象

从synchronized放置的位置不同可以得出,synchronized用来修饰方法时,是通过ACC_SYNCHRONIZED标识符来保持线程同步的。而用来修饰代码块时,是通过monitorenter和monitorexit指令来完成

  • volatile关键字的使用
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容