死锁
死锁:是指两个或两个以上的进程(线程)在执行过程中,因争夺资源而造成的一种相互等待的现象,若无外力作用,它们都将无法推进下去。
产生死锁的必要条件:
1、互斥条件:所谓互斥就是进程在某一时间内独占资源。
2、请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3、不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。
4、循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
活锁
活锁
:任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试, 失败,尝试,失败。
举个很简单的例子,两个人相向过独木桥,他们同时向一边谦让,这样两个人都过不去,然后二者同时又移到另一边,这样两个人又过不去了。如果不受其他因素干扰,两个人一直同步在移动,但外界看来两个人都没有前进,这就是活锁。
活锁会导致CPU耗尽的,解决办法是引入随机变量、增加重试次数等。
所以活锁也是程序设计上可能存在的问题,导致进程都没办法运行下去了,还耗CPU。
活锁和死锁的区别
活锁和死锁的区别在于,处于活锁的实体是在不断的改变状态,所谓的“活”, 而处于死锁的实体表现为等待;活锁有可能自行解开,死锁则不能。
饥饿
饥饿
:一个或者多个线程因为种种原因无法获得所需要的资源,导致一直无法执行的状态。
举个例子,当有多个进程需要打印文件时,如果系统分配打印机的策略是
最短文件优先,那么长文件的打印任务将由于短文件的源源不断到来而被无限期推迟,导致最终的饥饿甚至饿死。 进程饥饿,即为Starvation,指当等待时间给进程推进和响应带来明显影响称为进程饥饿。
Java 中导致饥饿的原因
:
1、高优先级线程吞噬所有的低优先级线程的 CPU 时间。
2、线程被永久堵塞在一个等待进入同步块的状态,因为其他线程总是能在它之前持续地对该同步块进行访问。
3、线程在等待一个本身也处于永久等待完成的对象(比如调用这个对象的 wait 方法),因为其他线程总是被持续地获得唤醒。