zoukankan      html  css  js  c++  java
  • Java多线程:线程死锁

    发生死锁的原因通常是两个对象的锁相互等待造成的。
    以下用一个实例来构造这样的情况:
    package basic.e_deadlock;
    
    import org.apache.log4j.Logger;
    
    public class TestDeadLock {
    	public static void main(String[] args) {
    		DeadlockRisk dead = new DeadlockRisk();
    		MyThread t1 = new MyThread(dead, 1, 2, "线程1");
    		MyThread t2 = new MyThread(dead, 3, 4, "线程2");
    		MyThread t3 = new MyThread(dead, 5, 6, "线程3");
    		MyThread t4 = new MyThread(dead, 7, 8, "线程4");
    		t1.start();
    		t2.start();
    		t3.start();
    		t4.start();
    	}
    }
    
    class MyThread extends Thread {
    	private DeadlockRisk dead;
    	private int a, b;
    
    	MyThread(DeadlockRisk dead, int a, int b, String threadName) {
    		this.dead = dead;
    		this.a = a;
    		this.b = b;
    		this.setName(threadName);
    	}
    
    	@Override
    	public void run() {
    		dead.read();
    		dead.write(a, b);
    	}
    }
    
    class DeadlockRisk {
    	private static Logger logger = Logger.getLogger(DeadlockRisk.class);
    	private static class Resource {
    		public int value;
    	}
    
    	private Resource resourceA = new Resource();
    	private Resource resourceB = new Resource();
    
    	public void read() {
    		logger.debug("===========read  begin===========");
    		synchronized (resourceA) {
    			logger.debug("read():" + Thread.currentThread().getName() + "获取了resourceA 的锁!");
    			synchronized (resourceB) {
    				logger.debug("read():" + Thread.currentThread().getName() + "获取了resourceB 的锁!");
    			}
    		}
    		logger.debug("===========read  end=============");
    	}
    
    	public void write(int a, int b) {
    		logger.debug("===========write begin===========");
    		synchronized (resourceB) {
    			logger.debug("write():" + Thread.currentThread().getName() + "获取了resourceB 的锁!");
    			synchronized (resourceA) {
    				logger.debug("write():" + Thread.currentThread().getName() + "获取了resourceA 的锁!");
    				resourceA.value = a;
    				resourceB.value = b;
    			}
    		}
    		logger.debug("===========write end=============");
    	}
    }
    运行结果:
    0    [线程1] DEBUG basic.e_deadlock.DeadlockRisk - ===========read  begin===========
    0    [线程2] DEBUG basic.e_deadlock.DeadlockRisk - ===========read  begin===========
    0    [线程4] DEBUG basic.e_deadlock.DeadlockRisk - ===========read  begin===========
    0    [线程3] DEBUG basic.e_deadlock.DeadlockRisk - ===========read  begin===========
    0    [线程1] DEBUG basic.e_deadlock.DeadlockRisk - read():线程1获取了resourceA 的锁!
    0    [线程1] DEBUG basic.e_deadlock.DeadlockRisk - read():线程1获取了resourceB 的锁!
    0    [线程1] DEBUG basic.e_deadlock.DeadlockRisk - ===========read  end=============
    0    [线程2] DEBUG basic.e_deadlock.DeadlockRisk - read():线程2获取了resourceA 的锁!
    0    [线程1] DEBUG basic.e_deadlock.DeadlockRisk - ===========write being===========
    1    [线程2] DEBUG basic.e_deadlock.DeadlockRisk - read():线程2获取了resourceB 的锁!
    1    [线程2] DEBUG basic.e_deadlock.DeadlockRisk - ===========read  end=============
    1    [线程2] DEBUG basic.e_deadlock.DeadlockRisk - ===========write being===========
    1    [线程1] DEBUG basic.e_deadlock.DeadlockRisk - write():线程1获取了resourceB 的锁!
    1    [线程4] DEBUG basic.e_deadlock.DeadlockRisk - read():线程4获取了resourceA 的锁!
    注意:此时线程1在等待resourceB的资源,线程2在等待resourceA的资源。两个线程在相互等待,出现死锁。
  • 相关阅读:
    [笔记]如何屏蔽视频网站的片头广告——优酷
    [翻译]JWA(JEDI Windows API Headers)库的readmefirst.txt文件翻译
    [代码]Delphi实现获取文件及文件夹大小(支持超过2G的大文件)
    [笔记]TrueCrypt7.0a代码编译流程 (已更新 TrueCrypt 7.2代码在Win8.1 64位下编译流程)
    学习一种编程语言必须要做的15个练习题(转发-收藏!)
    LoadRunner函数中文翻译系列之一Action
    软件配置项 的理解
    性能测试:压力测试、负载测试、并发测试、强度测试及容量测试之间的区别
    EF中使用泛型
    ASP.NET MVC 3.0 在各个版本IIS中的部署
  • 原文地址:https://www.cnblogs.com/yxwkf/p/3826735.html
Copyright © 2011-2022 走看看