java死锁的例子
16lz
2021-01-22
死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。
导致死锁的根源在于不适当地运用“synchronized”关键词来管理线程对特定对象的访问。“synchronized”关键词的作用是,确保在某个时刻只有一个线程被允许执行特定的代码块,因此,被允许执行的线程首先必须拥有对变量或对象的排他性的访问权。当线程访问对象时,线程会给对象加锁,而这个锁导致其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁。
由于这个原因,在使用“synchronized”关键词时,很容易出现两个线程互相等待对方做出某个动作的情形。代码一是一个导致死锁的简单例子。
package com.thread;
public class TestThread13 {
public static void main(String[] args) {
DeadLock t1 = new DeadLock();
DeadLock t2 = new DeadLock();
t1.flag = 1;
t2.flag = 0;
new Thread(t1).start();
new Thread(t2).start();
}
}
class DeadLock implements Runnable{
public int flag = 1 ;
static Object o1 = new Object(), o2 = new Object();
public void run() {
System.out.println("flag :"+flag);
if (flag == 1) {
synchronized (o1) {
System.out.println(Thread.currentThread().getName()+" o1 locked");
try{Thread.sleep(500);}catch(Exception e){e.printStackTrace();}
synchronized (o2) {
System.out.println(Thread.currentThread().getName()+" o2 locked");
System.out.println("1");
}
}
}
if (flag == 0) {
synchronized (o2) {
System.out.println(Thread.currentThread().getName()+" o2 locked");
try{Thread.sleep(500);}catch(Exception e){e.printStackTrace();}
synchronized (o1) {
System.out.println(Thread.currentThread().getName()+" o1 locked");
System.out.println("0");
}
}
}
}
}
运行结果:
分析:t1线程启动了,但并没有打印“1”;t2线程启动了,但并没有打印"0".因为2个线程启动后都阻塞了。
说明: t1线程启动后,占领监视器o1后,休眠500毫秒,这时t2线程占领了监视器o2,从此以后程序就堵塞了。正如截图结果。
原因是,t1线程占有监视器o1,等待t2线程释放监视器o2;同时,t2线程占有监视器o2,等待t1线程释放监视器o1, t1和t2这两个线程都在等对方先释放监视器,结果谁都不先释放,所以2个线程会一直堵塞。t1线程不能继续执行打印"1", t2线程不能继续执行打印“0”。
更多相关文章
- Java多线程之Thread、Runnable、Callable及线程池
- Java,Socket&TCP编程 实现多线程端对端通信与文件传输
- Java错误:线程“main”中的异常java.lang.ArrayIndexOutOfBoundsE
- Java并发面试题:三个线程轮流打印十次abc
- 【java】线程安全的整型类AtomicInteger
- Java多线程编程
- 线程“main”中的异常java.lang.RuntimeException:无法编译的源代
- Java ThreadPoolExecutor 线程池调度器
- Java多线程wait和notify协作,按序打印abc