Java线程知识整理(二)-synchronized和volatile

183 阅读1分钟

synchronized

给方法或代码块加锁,控制方法或代码块同一时间只有一个线程执行,解决并发问题。

synchronized代码块

使用monitorenter和monitorexit指令控制线程进出。

synchronized方法

方法用ACC_SYNCHRONIZED标识;

如果是static方法,锁作用在类上;

如果是非static方法,锁作用在具体的类对象上。

volatile

Java关键字,也是指令关键字。不具备锁的特性。

  1. 保证多线程间对变量的内存可见性,将最新变量值通知给其他线程。
  2. 禁止volatile前后的程序指令进行重排序。保证顺序性。
  3. 不保证线程安全。不保证原子性。

使用场景:

  1. 修饰状态变量:用于线程间访问该变量,保证各线程看到最新的内存值
  2. 单实例对象构造:避免多线程情况下由于内存不可见而重复多次构造对象

ReentrantLock

和synchronized相同点:

  1. 加锁,确保单线程执行。
  2. 一个线程获得锁,其余线程阻塞等待。
  3. 可重入锁。

和synchronized不同点:

  1. synchronized是Java关键字,由虚拟机字节码指令实现;ReentrantLock是Java sdk提供的API级别的锁实现。
  2. synchronized可以在方法级别锁,ReentrantLock则不行。
  3. ReentrantLock可以通过tryLock方法等待指定时间的锁,超时返回,synchronized不行。
  4. ReentrantLock提供了公平锁和非公平锁的实现,而synchronized只有非公平锁。

公平锁:按排队顺序轮流来获得锁。非公平锁:竞争获得锁。

(后续待写)