关于java多线程中的死锁问题(代码验证)!
锁死的现象:程序卡在某个地方,不再往下执行。开发中尽量避免这种现象发生。
死锁最常见的发生:锁的嵌套。
例如:有个任务需要2个以上的线程完成,但是线程获取锁的方式不同。
Thread-0需要先获取A锁,再获取B锁,才能去完成这个任务。
Thread-1需要先获取B锁,再获取A锁,才能完成这个任务。
程序正好运行到Thread-0获取A锁,正在准备获取B锁的时候cpu切换到Thread-1线程上,
Thread-1获取到的B锁,Thread-1需要获取A锁,而A锁被Thread-0已经获取到。
这时两个线程都需要获取对方线程已经持有的锁对象,线程任务不执行完,是不会主动释放锁的。
死锁的避免:
开发中尽量不要使用锁,如果有安全问题,能够使用一把锁解决的问题,千万别使用多把锁,并且锁嵌套。
死锁代码的演示:
package com.DeaeLock;
/*
* 多线程死锁练习
* */
public class DeadLock {
public static void main(String[] args) throws InterruptedException {
//创建多线程任务对象
DeadLockText DLT = new DeadLockText();
//创建俩个多线程
Thread T1 = new Thread(DLT);
Thread T2 = new Thread(DLT);
//启动第一个线程
T1.start();
//为了让主线程和现诚意能够有时间,所以执行完线程一睡眠3毫秒
Thread.sleep(3);//此处需要抛出异常
//改变flag的值,然后让俩个线程交换
DLT.flag = false;
//启动线程二,然后必然死锁
T2.start();
}
}
//定义一个多线程任务对象的类 利用第二种方法接了来实现多线程
class DeadLockText implements Runnable{
//利用Objetc来定义了俩吧锁 Object 属于所有对象的类
private Object Lock_A = new Object();
private Object Lock_B = new Object();
//定义了一个boolean变量flag
boolean flag = true;
//重写run方法
public void run() {
//利用双层嵌套实现死锁,写代码千万不能这样写,这只是演示一下死锁
if(flag){
while(true)//加了while接肯定会实现死锁
synchronized (Lock_A) {//同步代码块1
System.out.println(Thread.currentThread().getName()+" if....Lock_A");
synchronized (Lock_B) {//同步代码块2
System.out.println(Thread.currentThread().getName()+" if....Lock_B");
}
}
}else{
//以下同上
while(true)
synchronized (Lock_B) {
System.out.println(Thread.currentThread().getName()+" else....Lock_B");
synchronized (Lock_A) {
System.out.println(Thread.currentThread().getName()+" else....Lock_A");
}
}
}
}
}
浙公网安备 33010602011771号