本帖最后由 上篮高手 于 2013-10-19 12:00 编辑
以下是一个会产生死锁的例子:- package com.mingrisoft.thread;
- public class DeadLock implements Runnable {
- private boolean flag;// 使用flag变量作为进入不同块的标志
- private static final Object o1 = new Object();
- private static final Object o2 = new Object();
-
- public void run() {
- String threadName = Thread.currentThread().getName();// 获得当前线程的名字
- System.out.println(threadName + ": flag = " + flag);// 输出当前线程的flag变量值
- if (flag == true) {
- synchronized (o1) {// 为o1加锁
- try {
- Thread.sleep(1000);// 线程休眠1秒钟
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(threadName + "进入同步块o1准备进入o2");// 显示进入o1块
- synchronized (o2) {// 为o2加锁
- System.out.println(threadName + "已经进入同步块o2");// 显示进入o2块
- }
- }
- }
- if (flag == false) {
- synchronized (o2) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(threadName + "进入同步块o2准备进入o1");// 显示进入o2块
- synchronized (o1) {
- System.out.println(threadName + "已经进入同步块o1");// 显示进入o1块
- }
- }
- }
- }
-
- public static void main(String[] args) {
- DeadLock d1 = new DeadLock();// 创建DeadLock对象d1
- DeadLock d2 = new DeadLock();// 创建DeadLock对象d2
- d1.flag = true; // 将d1的flag设置为true
- d2.flag = false; // 将d2的flag设置为false
- new Thread(d1).start();// 在新线程中运行d1的run()方法
- new Thread(d2).start();// 在新线程中运行d2的run()方法
- }
- }
复制代码 Thread(d1)和 Thread(d2)启动后会分别进入不同的if 分支
此时Thread(d1) 占有锁01 Thread(d2) 占有锁o2
sleep后 Thread(d1) 会去请求资源o2 而 Thread(d2)会去请求资源o1
这样你不给我不让 就造成了死锁。
死锁的条件如下:
1: 资源互斥(资源只能供一个线程使用)
2: 请求保持(拥有资源的线程在请求新的资源又不释放占有的资源)
3: 不能掠夺(已经获得的资源在使用完成前不能掠夺)
4: 循环等待(各个线程对资源的需求构成一个循环)
以上例子的解决办法:- public void run() {
- String threadName = Thread.currentThread().getName();// 获得当前线程的名字
- System.out.println(threadName + ": flag = " + flag);// 输出当前线程的flag变量值
- if (flag == true) {
- synchronized (o1) {// 为o1加锁
- try {
- Thread.sleep(1000);// 线程休眠1秒钟
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(threadName + "进入同步块o1准备进入o2");// 显示进入o1块
- System.out.println(threadName + "已经进入同步块o2");// 显示进入o2块<font color="#ff0000"><b>***********注意少了synchronized (o2) </b></font>
- }
- if (flag == false) {
- synchronized (o2) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(threadName + "进入同步块o2准备进入o1");// 显示进入o2块
- synchronized (o1) {
- System.out.println(threadName + "已经进入同步块o1");// 显示进入o1块
- }
- }
- }
- }
复制代码 解决办法 : 对于这四个同步块,去掉任何一个就可以解决死锁的问题。
死锁的输出如下:Thread-0: flag = true
Thread-1: flag = false
Thread-1进入同步块o2准备进入o1
Thread-0进入同步块o1准备进入o2
|