Java死锁举例

死锁:

    在多线程竞争使用共享资源的情况下,就有可能出现死锁的情况。比如,当一个线程等待另一个线程所持有的锁时,那个线程又可能在等待第一个线程所持有的锁。此时,这两个线程会陷入无休止的相互等待状态,这种情况就称为死锁。

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

1、互斥条件。进程对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占有。

2、请求和保持条件。当进程因请求资源而阻塞时,对已获得的资源保持不放。

3、不剥夺条件。进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。

4、环路等待条件。在发生死锁时,必然存在一个进程-资源的环形链,即进程集合{P1,P2,。。。,Pn}中的P1等待一个P2占用的资源,P2正在等待一个P3占用的资源,。。。,Pn正在等待已被P1所占用的资源。


比较简单的解决死锁的方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。预防死锁是一种较易实现的方法,已被广泛使用。但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率和系统吞吐量降低。

下面是产生死锁的一个示例:

package com.hh.deadLock;

public class DeadLockDemo {

	public static void main(String[] args) {
		final Object resource1 = "资源1";
		final Object resource2 = "资源2";
		Thread t1 = new Thread(){
			public void run() {
				synchronized(resource1){
					System.out.println("线程1:获取资源1使用权");
					try {
						Thread.sleep(500);
					} catch (Exception e) {	}
					synchronized(resource2){
						System.out.println("线程1:等待资源2");
					}
				}
			}
		};
		Thread t2 = new Thread(){
			public void run() {
				synchronized(resource2){
					System.out.println("线程2:获取资源2使用权");
					try {
						Thread.sleep(500);
					} catch (Exception e) {	}
					synchronized(resource1){
						System.out.println("线程2:等待资源1");
					}
				}
			}
		};
		
		t1.start();
		t2.start();
	}
}

程序会先打印出

线程1:获取资源1使用权
线程2:获取资源2使用权
或者是

线程2:获取资源2使用权
线程1:获取资源1使用权
然后程序就不再往下执行

线程t1获取“资源1”使用权后等待“资源2”,而线程t2获取“资源2”使用权后等待“资源1”,这样,线程t1和线程t2就引起了死锁。

如果将程序中的Thread.sleep(500);这行代码注释,则程序可能引起死锁,也可能不引起。

Java中,死锁是指多个线程相互等待对方释放锁,导致所有线程都无法继续执行的一种情况。下面举一个简单的例子说明如何实现一个死锁: ```java public class Deadlock { private static Object lock1 = new Object(); private static Object lock2 = new Object(); public static void main(String[] args) { Thread thread1 = new Thread(() -> { synchronized (lock1) { System.out.println("Thread 1 acquired lock1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock2) { System.out.println("Thread 1 acquired lock2"); } } }); Thread thread2 = new Thread(() -> { synchronized (lock2) { System.out.println("Thread 2 acquired lock2"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock1) { System.out.println("Thread 2 acquired lock1"); } } }); thread1.start(); thread2.start(); } } ``` 在这个例子中,我们定义了两个对象锁lock1和lock2,并通过两个线程thread1和thread2分别获取这两个锁。当thread1获取到lock1锁之后,尝试获取lock2锁,而此时lock2已经被thread2获取,因此thread1会一直等待lock2的释放。而thread2同样也会等待thread1释放lock1锁。这样就形成了一个死锁,所有线程都无法继续执行。 需要注意的是,死锁是一种非常危险的情况,会导致应用程序的崩溃和数据丢失。因此,在编写多线程程序时,需要注意避免死锁的发生,例如避免多个线程同时获取多个锁、按照相同的顺序获取锁等等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值