java 线程死锁

下面是一个由于同步导致线程死锁的例子:

package com.cn.gao;

public class ThreadLock implements Runnable{

	private static Object obj1 = new Object();  //此处必须定义为static变量,这样才能使两个线程共享一个资源变量
	private static Object obj2 = new Object();  
	Boolean flag = true;
	
	@Override
	public void run() {
		
		if(flag){
			synchronized(obj1){
				System.out.println(Thread.currentThread().getName() + ":我已经锁定obj1,休息2s就去锁定obj2");
				
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized(obj2){
					System.out.println(Thread.currentThread().getName() + ":我已锁定全部资源");
				}
			}
		}else{
			synchronized(obj2){
				System.out.println(Thread.currentThread().getName() + ":我已经锁定obj2,休息2s就去锁定obj1");
				
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized(obj1){
					System.out.println(Thread.currentThread().getName() + ":我已锁定全部资源");
				}
			}
		}		
		
	}
	
	public static void main(String args[]){
		ThreadLock t1 = new ThreadLock();
		ThreadLock t2 = new ThreadLock();
		
		t1.flag = true;
		t2.flag = false;
		
		Thread thread1 = new Thread(t1,"线程1");
		Thread thread2 = new Thread(t2,"线程2");
		
		thread1.setPriority(Thread.MAX_PRIORITY);
		thread2.setPriority(Thread.MIN_PRIORITY);
		
		thread1.start();
		thread2.start();
		
	}
	

}
输出:
<pre name="code" class="plain" style="color: rgb(56, 56, 56); font-size: 14px; line-height: 21.9999923706055px;">线程1:我已经锁定obj1,休息2s就去锁定obj2
线程2:我已经锁定obj2,休息2s就去锁定obj1

 

那么为什么会产生死锁呢?
1.因为系统资源不足。
2.进程运行推进的顺序不合适。    
3.资源分配不当。
             
学过操作系统的朋友都知道:产生死锁的条件有四个:
1.互斥条件:所谓互斥就是进程在某一时间内独占资源。(就是说多个线程在某个时间内不能同时使用某一资源
2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。(占有等待)(就是说一个线程需要拥有多个资源才能完成任务,他将一直占有已拥有的资源直到他拥有全部所需要的资源)
3.不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。(所有的线程优先级相同,不能在别的线程没有释放资源的情况下强行夺走其资源)
4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。(没有资源满足的线程无限期的等待


如何解决死锁,大家可以从死锁的四个条件去解决,只要破坏了一个必要条件,那么我们的死锁就解决了。在java中使用多线程的时候一定要考虑是否有死锁的问题哦。
  • 打破互斥条件
如果想要打破这个条件,就是要让多个线程共享资源,比如说一个读线程,还有一个写线程,如果他们可以同时操作同一个文件,则有可能读到脏数据。所以一般不从这方面考虑打破死锁

  • 打破占有等待
当检测到自己所需要的资源被别的线程占用,则立即释放自己占用的资源,或者等待某一固定时间,若还没有得到该资源,则立即释放自己所拥有的资源

  • 打破不剥夺条件
给所以的线程设定优先级,如有三个线程(优先级从高到低)A/B/C,当A需要某个资源时,如果此时C正在占用他,因为A的优先级高于C,所以C必须立马释放该资源

  • 打破循环等待条件
如果等待一段时间,还没有得到自己所需要的资源,则立马释放自己拥有的所有资源

下面是通过wait()方法释放对同步监视器的锁定,然后再通过notifyAll()释放对同步监视器的锁定
package com.cn.gao;

public class ThreadLock implements Runnable{

	private static Object obj1 = new Object();  //此处必须定义为static变量,这样才能使两个线程共享一个资源变量
	private static Object obj2 = new Object();  
	Boolean flag = true;
	
	@Override
	public void run() {
		
		if(flag){
			synchronized(obj1){
				System.out.println(Thread.currentThread().getName() + ":我已经锁定obj1,休息2s就去锁定obj2");
				
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				//先调用obj1的wait()方法,导致当前线程等待,且当前线程会释放对同步监视器的锁定
				try {
					obj1.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized(obj2){
					System.out.println(Thread.currentThread().getName() + ":我已锁定全部资源");
				}
			}
		}else{
			synchronized(obj2){
				System.out.println(Thread.currentThread().getName() + ":我已经锁定obj2,休息2s就去锁定obj1");
				
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized(obj1){
					System.out.println(Thread.currentThread().getName() + ":我已锁定全部资源");
					obj1.notifyAll();    //唤醒在此同步监视器上等待的所有线程
				}
			}
		}		
		
	}
	
	public static void main(String args[]){
		ThreadLock t1 = new ThreadLock();
		ThreadLock t2 = new ThreadLock();
		
		t1.flag = true;
		t2.flag = false;
		
		Thread thread1 = new Thread(t1,"线程1");
		Thread thread2 = new Thread(t2,"线程2");
		
		
		thread1.start();
		thread2.start();
		
	}
	

}
输出:
线程1:我已经锁定obj1,休息2s就去锁定obj2
线程2:我已经锁定obj2,休息2s就去锁定obj1
线程2:我已锁定全部资源
线程1:我已锁定全部资源



虽然目前已经知道解决死锁的方法,但是具体应该怎么操作还不是很清楚。

比如说打破不剥夺条件里面:如有三个线程(优先级从高到低)A/B/C,当A需要某个资源时,如果此时C正在占用他,因为A的优先级高于C,所以C必须立马释放该资源

我是如何知道线程c正在占用该资源,如有人知道麻烦告知一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值