多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源
都停止执行的情形,某一个同步块同时 拥有”两个以上对象的锁“时,就可能发生死锁的问题
//死锁:多个线程互相抱着对方需要的资源,然后形成僵持
public class Main {
public static void main(String[] args) {
//0,为口红,1为镜子
Makeuo g1=new Makeuo(0,"小红帽");//第一个人
Makeuo g2=new Makeuo(1,"灰姑娘");//第二个人
//启动这两个线程
g1.start();
g2.start();
}
}
//口红
class Lipatic{
}
//镜子
class Mirrot{
}
//化妆
class Makeuo extends Thread{
//需要的资源只有一份,用static来保证只有份
static Lipatic lip=new Lipatic();//创建一个口红对象
static Mirrot mir=new Mirrot();//创建一个镜子对象
int choice;//选择
String girLnmae;//使用化妆品的人
//构造器
Makeuo(int choice,String girLnmae){
this.choice=choice;
this.girLnmae=girLnmae;
}
public void run(){
//化妆
makeup();
}
//化妆方法,互相持有对方的锁,就是需要拿到对方的
private void makeup(){
//这是第一个人,先拿口红
if(choice==0){
synchronized(lip){//获得口红的锁
System.out.println(this.girLnmae+"获得口红的锁");
//休息一秒
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("休息异常");
}
//休息后想拿到镜子
synchronized(mir){//一秒钟后想获得镜子
System.out.println(this.girLnmae+"获得镜子的锁");
}
}
}else{//这是第二个人,先拿镜子,这样做判断,就可以让他们互相都想获取对方的资源
synchronized(mir){//获得镜子的锁
System.out.println(this.girLnmae+"获得镜子的锁");
//休息2秒
try {
Thread.sleep(2000);
} catch(Exception e) {
System.out.println("休息异常");
}
//休息后想拿到镜子
synchronized(lip){//2秒钟后想获得口红
System.out.println(this.girLnmae+"获得口红的锁");
}
}
}
}
}
//死锁:多个线程互相抱着对方需要的资源,然后形成僵持,解决方式
public class Main {
public static void main(String[] args) {
//0,为口红,1为镜子
Makeuo g1=new Makeuo(0,"小红帽");//第一个人
Makeuo g2=new Makeuo(1,"灰姑娘");//第二个人
//启动这两个线程
g1.start();
g2.start();
}
}
//口红
class Lipatic{
}
//镜子
class Mirrot{
}
//化妆
class Makeuo extends Thread{
//需要的资源只有一份,用static来保证只有份
static Lipatic lip=new Lipatic();//创建一个口红对象
static Mirrot mir=new Mirrot();//创建一个镜子对象
int choice;//选择
String girLnmae;//使用化妆品的人
//构造器
Makeuo(int choice,String girLnmae){
this.choice=choice;
this.girLnmae=girLnmae;
}
public void run(){
//化妆
makeup();
}
//化妆方法,互相持有对方的锁,就是需要拿到对方的
private void makeup(){
//这是第一个人,先拿口红
if(choice==0){
synchronized(lip){//获得口红的锁
System.out.println(this.girLnmae+"获得口红的锁");
//休息一秒
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("休息异常");
}
//原本拿镜子的代码块是放在这里的,我们把他放到循环外面,不要同时抱对方的锁,就可以了
}
//休息后想拿到镜子
synchronized(mir){//一秒钟后想获得镜子
System.out.println(this.girLnmae+"获得镜子的锁");
}
}else{//这是第二个人,先拿镜子,这样做判断,就可以让他们互相都想获取对方的资源
synchronized(mir){//获得镜子的锁
System.out.println(this.girLnmae+"获得镜子的锁");
//休息2秒
try {
Thread.sleep(2000);
} catch(Exception e) {
System.out.println("休息异常");
}
//原本拿口红的代码块是放在这里的,我们把他放到循环外面,不要同时抱对方的锁,就可以了
}
//休息后想拿到口红
synchronized(lip){//2秒钟后想获得口红
System.out.println(this.girLnmae+"获得口红的锁");
}
}
}
}
死锁总结:
解决死锁的方法是,不要同时抱对方需要的锁
产生条件:
1.互斥条件:一个资源每次只能被一个进程使用。
2.请求与保持条件:一个进程因请求资源而阻塞时,对方获得的资源保持不放。
3.不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
上面的条件,我们只要想办法破解其中任意一个或者多个条件,就可避免死锁发生。