Java多线程-线程安全

线程安全问题的原因:

  1. 存在共享数据(也被称为临界资源)
  2. 存在多条线程共同操作这些数据的情况

解决方法:

  在同一时刻,有且只有一个线程操作这些数据;其他线程必须等到这个线程,再对共享数据进行操作

互斥锁

  • 互斥性:在同一时间,只有一个线程,持有某个对象锁。通过这种特性,来实现多线程的协调机制。在同一时间,只有一个线程对需要同步的代码块进行访问。互斥性,也被称为操作的原子性
  • 可见性:必须确保在锁被释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程是可见的(也就是,在获得锁时,应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作,从而引起不一致。另一个锁在获取共享数据时,是最新的值
  • synchronized 锁的是对象,不是代码

synchronized:

根据获取的锁的分类:获取对象锁 和 获取类锁

获取对象锁的两种用法:

  1. 同步代码块:synchronized (this):
    • synchronized 类实例对象
    • this,小括号中的就是实例对象
  2. 同步非静态方法: synchronized method:
    • 锁时当前对象的实例对象

获取类锁的两种用法:(通过 对象锁实现的类锁)

    • 同步代码块:synchronized (类.class):
      • 锁是 ()小括号中的就是 类对象(class对象)
    • 同步静态方法: synchronized static method:
      • 锁时当前对象的类对象(class对象)

对象锁和类锁的总结:

  • 有线程访问对象的同步代码块时,另外的线程可以访问该对象的非同步代码块
  • 若锁住的是同一个对象,一个线程在访问对象的同步代码块时,另一个访问的对象的同步代码块的线程被阻塞
  • 若锁住的是同一个对象,一个线程在访问对象的同步方法时,另一个访问对象的同步方法的线程会被阻塞
  • 若锁住的是同一个对象,一个线程在访问对象的同步代码块时,另一个访问对象同步方法的线程会被阻塞,反之亦然
  • 同一个类的不同对象的对象锁互不干扰
  • 类锁,由于也是一种特殊的对象锁,因此表现的同上述四点一致;而由于一个类只有一把对象锁,所以同一个类的不同对象使用类锁,将会是同步的
  • 类锁和对象锁互不干扰

synchronized的底层原理:

monitor:每个Java对象都天生带着存在一个看不见的锁🔐

posted @ 2019-07-24 20:25  豆芽花花儿酱  阅读(163)  评论(0编辑  收藏  举报