Java 死锁面试,Java后台研发-面试攻略-死锁

1. 什么是死锁?

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

例如:当线程进入对象的synchronized代码块时,便占有了资源,直到它退出该代码块或者调用wait方法,才释放资源,在此期间,其他线程将不能进入该代码块。简而言之,当线程互相持有对方所需要的资源时,会互相等待对方释放资源,如果线程都不主动释放所占有的资源,将产生死锁。

2. 产生死锁的必要条件

互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。

请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。

非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。

循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。

3. 如何预防死锁?

如果一个线程只能获得一个锁那就就不会发生死锁,当然这是很难实现的。

以确定的顺序获得锁。在设计程序的时候,充分考虑不同线程之前获得锁的顺序。

超时放弃。当使用synchronized关键词提供的内置锁时,只要线程没有获得锁,那么就会永远等待下去,然而Lock接口提供了boolean tryLock(long time, TimeUnit unit) throws InterruptedException方法,该方法可以按照固定时长等待锁,因此线程可以在获取锁超时以后,主动释放之前已经获得的所有的锁。通过这种方式,也可以很有效地避免死锁。

4. 如何发现死锁?

jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息。通过jstack命令查看线程堆栈信息,可以发现死锁

jonny@~$ jstack -F 1362

Attaching to process ID 1362, please wait...

Debugger attached successfully.

Server compiler detected.

JVM version is 23.21-b01

Deadlock Detection:

Found one Java-level deadlock:

=============================

"Thread-1":

waiting to lock Monitor@0x00007fea1900f6b8 (Object@0x00000007efa684c8, a java/lang/Object),

which is held by "Thread-0"

"Thread-0":

waiting to lock Monitor@0x00007fea1900ceb0 (Object@0x00000007efa684d8, a java/lang/Object),

which is held by "Thread-1"

Found a total of 1 deadlock.

通过JConsole工具也可以检测死锁

5. 代码模拟死锁

public class App{

public static void main(String[] args) {

final Object a = new Object();

final Object b = new Object();

Thread threadA = new Thread(new Runnable() {

public void run() {

synchronized (a) {

try {

System.out.println("now i in threadA-locka");

Thread.sleep(1000l);

synchronized (b) {

System.out.println("now i in threadA-lockb");

}

} catch (Exception e) {

// ignore

}

}

}

});

Thread threadB = new Thread(new Runnable() {

public void run() {

synchronized (b) {

try {

System.out.println("now i in threadB-lockb");

Thread.sleep(1000l);

synchronized (a) {

System.out.println("now i in threadB-locka");

}

} catch (Exception e) {

// ignore

}

}

}

});

threadA.start();

threadB.start();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值