Java-死锁

Java中的锁一般指内置锁,也称互斥锁。

多个线程对共享资源进行访问时,只有一个线程可以获取到该共享资源的锁,当线程B获取到锁,线程A尝试访问时,线程A必须等待或阻塞,直到线程B释放该锁。一个Synchronized块包含两部分:锁以及这个锁保护的代码块。执行线程进入Synchronized块之前会自动获得锁,获得锁的唯一途径是进入这个内部锁保护的同步块或方法,正常退出执行过程中抛出异常时线程会放弃对Synchronized块的控制并释放锁。

每个java对象都可以作为一个实现同步的锁,锁只能是引用类型。根据使用方式的不同我们将锁分为对象锁类锁,对象锁作用在实例方法或实例对象上,类锁作用在静态方法或Class对象上。一个类可以有多个实例对象,所以一个类的对象锁可能会有多个,但是每个类只有一个Class对象,所以类锁只有一个。


死锁:多个并发进程因争夺系统资源而发生互相等待的现象。造成此种现象的主要是因为系统资源有限以及进程推进顺序不合理。

死锁产生的4个必要条件:

1.互斥:资源一次只能被一个线程访问;

2.占有且等待:一个线程已经占有资源(一个或多个),同时还有资源未被满足,正在等待其他线程释放;

3.不可抢占:资源一旦被其他线程占用,不能将此资源抢过来;

4.循环等待:每一个线程占有另一个线程所需的至少一种资源;

避免死锁方法举例:

1.破坏占有且等待:所有线程在运行之前,一次性占用运行过程中全部所需资源

优点:简单且安全

缺点:造成资源浪费,缺少某项资源则无法启动,另外,已经占用的资源也无法被使用;发生饥饿现象

改良:只占用运行初期需要的资源,执行过程中逐步释放使用完毕的资源并占用新资源

2.破坏不可抢占:已经占有资源的无法占有其他资源时,释放已经占有的资源,等到有需要再重新申请

 


死锁举例

/**
 * @className DeadLock
 * @description 死锁举例
 * @author BSmile
 * @date 2018年3月18日 下午10:52:04
 */
public class DeadLock {
	/** 对象锁1 */
	public static String objLock1 = "objLock1";
	/** 对象锁2 */
	public static String objLock2 = "objLock2";
	
	public static void main(String[] args) {
		//同时启动两个并发线程,Lock1先获取对象锁1,Lock2获取对象锁2,
		//然后让Lock1去获取对象锁2,Lock2获取对象锁1,
		//因为都没有释放锁,所以同时都获取不到,所以造成死锁
		new Thread(new Lock1()).start();
		new Thread(new Lock2()).start();
	}
}
/**
 * @className Lock1
 * @description Lock1先获取对象锁1,再去获取对象锁2,发现对象锁2被Lock2占用了
 * @author BSmile
 * @date 2018年3月18日 下午11:00:29
 */
public class Lock1 implements Runnable {

	@Override
	public void run() {
		System.out.println("Lock1 running");
		synchronized (DeadLock.objLock1) {
			System.out.println("Lock1 get objLock1");
			try {
				//Lock1获取到对象锁1等待3秒,让Lock2获取对象锁2
				Thread.sleep(3*1000);
				synchronized (DeadLock.objLock2) {
					System.out.println("Lock1 get objLock2");
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
/**
 * @className Lock2
 * @description Lock2先获取对象锁2,再去获取对象锁1,发现对象锁1被Lock1占用了
 * @author BSmile
 * @date 2018年3月18日 下午11:30:26
 */
public class Lock2 implements Runnable {

	@Override
	public void run() {
		System.out.println("Lock2 running");
		synchronized (DeadLock.objLock2) {
			System.out.println("Lock2 get objLock2");
			try {
				//Lock2获取到对象锁2等待3秒,让Lock1获取对象锁1
				Thread.sleep(3*1000);
				synchronized (DeadLock.objLock1) {
					System.out.println("Lock2 get objLock1");
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
	}
}

运行结果如下:

Lock1 running
Lock1 get objLock1
Lock2 running
Lock2 get objLock2

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值