一、synchronized
(1)synchronized方法
(2)synchronized块
二、Lock
注意:及时释放Lock锁,否则会出现死锁,通常在finally代码释放锁
(1)ReentrantLock
实现Lock接口,提供lock(),tryLock()和unLock()方法。
lock() 获取锁
tryLock() 尝试获取锁,返回true/false
unlock() 释放获得的锁
(2)ReentrantReadWriteLock
实现ReadWriteLock接口,并非Lock接口。
readLock()方法获取可读锁对象是Lock的实例,可读锁对象是共享锁
writeLock()方法获取可写锁Lock对象是Lock的实例,可写锁对象是排他锁
三、volatile关键字
volatile关键字为域变量的访问提供了一种免锁机制, 使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新, 因此每次使用该域就要重新计算,而不是使用寄存器中的值。
volatile只能保证代码的可见性,而不能保证代码的原子性。
volatile不会提供任何原子操作,它也不能用来修饰final类型的变量 。
volatile关键字具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2)禁止进行指令重排序。
使用场景:
1)对变量的写操作不依赖于当前值,如i++
2)该变量没有包含在具有其他变量的不变式中,如low<up
四、ThreadLocal类
ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本, 副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。
ThreadLocal 类的常用方法
get() 返回此线程局部变量的当前线程副本中的值
initialValue() 返回此线程局部变量的当前线程的初始值"
set(T value) 将此线程局部变量的当前线程副本中的值设置为value
五、使用阻塞队列实现线程同步
BlockingQueue接口和BlockingDeque,使用ReentrantLock
ArrayBlockingQueue
LinkedBlockingQueue
LinkedBlockingDeque
SynchronousQueue
阻塞方法put、take
非阻塞方法offer与poll、add与remove
六、原子变量实现线程同步
java.util.concurrent.atomic包
(1)使用volatile和CAS算法
AtomicBoolean
AtomicInteger
AtomicIntegerArray
AtomicLong
AtomicLongArray
AtomicReference
AtomicReferenceArray
AtomicStampedReference
(2)使用Striped64和Cell(volatile和CAS)
LongAccumulator
LongAdder
DoubleAccumulator
DoubleAdder
七、wait与notify()/notifyAll()
Object类的成员方法,在同步代码区使用
wait 阻塞线程
notify 唤醒阻塞线程
notifyAll 唤醒所有阻塞线程