private final static Object MUTEX_READ = new Object();
private final static Object MUTEX_WRITE = new Object();
public void read(){
synchronized (MUTEX_READ) {
synchronized (MUTEX_WRITE) {
}
}
}
public void write(){
synchronized (MUTEX_WRITE) {
synchronized (MUTEX_READ) {
}
}
}
服务器开启了某个端口,等待客户端的访问。客户端发送请求后等待服务器的响应,服务器由于某种缘由错过了客户端的请求,让在等待请求。此时,服务端可客户端都在等待对方发送数据。
好比某个线程执行了for update语句后退出了事务,其余线程访问的时候就会陷入死锁
获取文件锁的线程意外退出,其它线程没法获取该文件锁会进入死锁。
处理死锁的方法服务器
经过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或几个条件,来防止死锁的发生。【在死锁产生的四个必要条件中,“互斥条件”是没法破坏的,破坏“互斥条件”会形成结果的不可再现性】数据结构
容许对资源实行抢夺。
方法一:若是占有某些资源的一个线程进行进一步资源请求被拒绝,则该线程必须释放它最初占有的资源【若是有须要,可再次请求这些资源和另外的资源】。
方法二:容许优先级高的线程抢占优先级低的线程的资源。
在系统中不容许进程在已得到某种资源的状况下,申请其余资源。
方法一:采用“ 一次性分配”方案,即:建立进程时,要求它申请所需的所有资源,系统或知足其全部要求,或什么也不给它。
方法二:要求每一个进程提出新的资源申请前,释放它所占有的资源。
将系统中的全部资源进行编号,线程必须按照顺序申请资源。
避免死锁的处理方式
主要是针对那些不可能实现按序加锁而且锁超时也不可行的场景。每当一个线程请求或者得到了锁,会在线程和锁相关的数据结构中将其记下。
线程A等待线程B,线程B等待线程C,线程C等待线程D,线程D又在等待线程A。线程A为了检测死锁,它须要递进地检测全部被B请求的锁。从线程B所请求的锁开始,线程A找到了线程C,而后又找到了线程D,发现线程D请求的锁被线程A本身持有着。这是它就知道发生了死锁。
检测和解除死锁
因为操做系统有并发、共享以及随机性等特色,经过预防和避免的手段达到排除死锁的目的是很困难的。一种简便的方法是系统为进程分配资源时,不采起任何限制性措施,可是提供了检测和解脱死锁的手段:能发现死锁并从死锁状态中恢复出来。所以,在实际的操做系统中每每采用死锁的检测和解除方法来排除死锁。
死锁检测和解除是指系统设有专门的机制,当死锁发生时,该机制可以检测到死锁发生的位置和缘由,并能经过外力破坏死锁发生的必要条件,从而使得并发进程从死锁状态中恢复出来。
1) 资源剥夺法:挂起某些死锁进程,并释放它的资源,将这些资源分配给其余的死锁进程。【但应防止被挂起的进程长时间得不到资源,而处于资源匮乏的状态】
2) 撤销线程法:强制撤销部分、甚至所有死锁线程。【撤销的原则能够按进程优先级和撤销进程代价的高低进行】
3) 进程回退法:让一(多)个线程回退到足以回避死锁的地步【要求系统保持进程的历史信息,设置还原点】