synchronized
给方法或代码块加锁,控制方法或代码块同一时间只有一个线程执行,解决并发问题。
synchronized代码块
使用monitorenter和monitorexit指令控制线程进出。
synchronized方法
方法用ACC_SYNCHRONIZED标识;
如果是static方法,锁作用在类上;
如果是非static方法,锁作用在具体的类对象上。
volatile
Java关键字,也是指令关键字。不具备锁的特性。
- 保证多线程间对变量的内存可见性,将最新变量值通知给其他线程。
- 禁止volatile前后的程序指令进行重排序。保证顺序性。
- 不保证线程安全。不保证原子性。
使用场景:
- 修饰状态变量:用于线程间访问该变量,保证各线程看到最新的内存值
- 单实例对象构造:避免多线程情况下由于内存不可见而重复多次构造对象
ReentrantLock
和synchronized相同点:
- 加锁,确保单线程执行。
- 一个线程获得锁,其余线程阻塞等待。
- 可重入锁。
和synchronized不同点:
- synchronized是Java关键字,由虚拟机字节码指令实现;ReentrantLock是Java sdk提供的API级别的锁实现。
- synchronized可以在方法级别锁,ReentrantLock则不行。
- ReentrantLock可以通过tryLock方法等待指定时间的锁,超时返回,synchronized不行。
- ReentrantLock提供了公平锁和非公平锁的实现,而synchronized只有非公平锁。
公平锁:按排队顺序轮流来获得锁。非公平锁:竞争获得锁。
(后续待写)