管程: 管理共享变量 以及 对共享变量操作的过程 ===》 管程是一种高级的同步机制,,它将共享资源,,对资源的操作 以及线程的同步(如加锁和等待)封装在一个抽象数据类型或者对象中
有两个特点:
- 互斥: 共享变量和 对共享变量的操作都封装起来,,只允许一个线程进入管程
- 同步: 线程之前如何通讯协作
线程通过条件变量,,去判断加入哪一个等待队列,,当使用notify() 只会随机一个对待队列中的线程,,进入入口等待队列,,,
java中管程的实现:
-
synchronized
和 Object 中的wait()
.,notify()
,notifyAll
… -
ReentrantLock
和Condition
,, condition的await()
,signal()
,signalAll()
ReentrantLock 的好处: 响应中断,支持超时,,非阻塞的获取锁
lock.lockInterruptibly()
这个会去尝试获取锁,,如果interrupt()
中断线程,会抛出InterruptedException
- ReentrantLock可以设置等待时间。
tryLock(1,TimeUnit.SECONDS)
在指定时间内获取锁,,如果获取不到,返回false,线程不会被阻塞 tryLock()
非阻塞获取锁,如果锁不可用,立即返回false- 公平锁 : 谁等待的时间长,就执行谁
new ReentrantLock(true)
这个锁可以将异步的方法,变成同步执行 ==》。在读和写的时候都加上一个锁,进入队列和 出队列,,检测到队列不为空就出队列,如果队列为空,让出锁,,写的时候获取锁,,写完之后,让出锁
读写锁ReadWriteLock
ReentrantReadWriteLock
. 是可重入锁,,这里面有一个读锁和写锁
写锁是独占锁
,一旦线程获取到了写锁,,其他线程不管是 读 还是 写 ,,都必须等待这个写锁释放,,才会执行
读锁是共享锁
,可以多个线程同时读取共享变量,,但是会被写锁阻塞
因为是可重入锁,,如果在一个读锁里面 嵌套一个 写锁 ,,可能会出现死锁问题,,,这种叫 锁的升级
,,锁的升级通常是不安全的。。。。
ReadWriteLock不允许将读锁 升级为 写锁:升级锁会形成死锁
写锁可以降级为读锁,,读锁是共享的,,在写锁释放后,