龙空技术网

Java面试题之程序什么情况会发生死锁?如何定位、解决?

大叔程序猿 238

前言:

而今咱们对“java死锁例子”大致比较讲究,小伙伴们都需要学习一些“java死锁例子”的相关知识。那么小编同时在网摘上网罗了一些有关“java死锁例子””的相关文章,希望朋友们能喜欢,小伙伴们快快来学习一下吧!

答:

死锁是由于循环依赖导致导致彼此一直处于等待之中,没有任何个体可以继续前进执行的状态。

死锁不仅会在线程间发生,存在资源独占的进程间同样可能发生,但通常我们说的是多线程中的死锁,指两个或多个线程间,由于持有对方需要的所,而永远处于阻塞的状态。如下图:

示例图1

定位死锁最常用的方式就是利用jdk自带的jstack、jps等工具获取线程栈,然后定位互相之间的依赖关系,进而找到死锁

如果程序发生了死锁,绝大多数情况下是无法在线解决问题的,只能找到代码的bug,修复后重新上线。所以在代码开发阶段要在小组间review代码,由于是设计到多线程和锁的地方。

避免死锁的几个常用方法:

1.尽量避免一个线程同时获取多个锁

2.尝试使用超时锁,如lock.tryLock(timeout)

3.对于数据库锁,加锁和解锁必须在一个数据库连接里

死锁代码示例:

import java.util.concurrent.TimeUnit;public class DeadLockDemo {	private static final Object LOCK_A = new Object();	private static final Object LOCK_B = new Object();		public void deadLock() {		Thread thread1 = new Thread(new Runnable() {						@Override			public void run() {				synchronized (LOCK_A) {					System.out.println("thread1 get lock_a");					try {						TimeUnit.SECONDS.sleep(1);					} catch (InterruptedException e) {						// TODO Auto-generated catch block						e.printStackTrace();					}					synchronized (LOCK_B) {						System.out.println("thread1 get lock_b");					}									}			}		});		Thread thread2 = new Thread(new Runnable() {						@Override			public void run() {				synchronized (LOCK_B) {					System.out.println("thread2 get lock_b");					try {						TimeUnit.SECONDS.sleep(1);					} catch (InterruptedException e) {						// TODO Auto-generated catch block						e.printStackTrace();					}					synchronized (LOCK_A) {						System.out.println("thread2 get lock_a");					}									}							}		});		thread1.start();		thread2.start();	}		public static void main(String[] args) {		new DeadLockDemo().deadLock();	}}

死锁定位:1.先用jps找到对应的线程

2.利用jstack pid查看线程栈信息

如下图:

示例图2

标签: #java死锁例子 #java死锁是什么意思