Java 线程同步总结

一、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   唤醒所有阻塞线程

 

posted @ 2017-09-18 17:09  茅坤宝骏氹  阅读(157)  评论(0编辑  收藏  举报