死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

导致死锁的根源在于不适当地运用“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”。

更多相关文章

  1. Java多线程之Thread、Runnable、Callable及线程池
  2. Java,Socket&TCP编程 实现多线程端对端通信与文件传输
  3. Java错误:线程“main”中的异常java.lang.ArrayIndexOutOfBoundsE
  4. Java并发面试题:三个线程轮流打印十次abc
  5. 【java】线程安全的整型类AtomicInteger
  6. Java多线程编程
  7. 线程“main”中的异常java.lang.RuntimeException:无法编译的源代
  8. Java ThreadPoolExecutor 线程池调度器
  9. Java多线程wait和notify协作,按序打印abc

随机推荐

  1. 【一步一个脚印】Tomcat+MySQL为自己的AP
  2. 如何将A表查出来的数据放到B表中
  3. 存款日均额计算的SQL语句如何书写
  4. SQLSERVER中的假脱机spool
  5. [超入门]使用docker做mysql主从复制实验
  6. laravel原生MySQL之Group记录
  7. 高分求解:如何每天将本地的sybase的数据导
  8. MySQL 5.7.22 免安装配置
  9. MySQL数据库阶段学习目录
  10. 临时表空间、drop、truncate、delete的区