java中动态顺序死锁问题
作者:互联网
一般来说,死锁产生的原因是因为获取锁的顺序不一致,所以如果有顺序的将锁写入程序内。就可以解决死锁,但是如果锁是某个方法的入参,那么就会造成动态死锁问题,比如说你设置了两把锁,分别为方法的两个入参a,b,锁的顺序也在方法内实现了,先锁a,再锁b,此时有两个线程A,B,A传入a->x对象,b->y对象;B传入a->y对象,b->x对象,线程A进入方法后锁住了第一把锁x对象准备获取y锁的时候,线程B锁住了y对象准备获取x锁,这样就会造成动态死锁,你无法控制外部的传参。
解决方法1:使用hashcode,为了避免对象重写hashcode,使用identityHashCode方法算两个传入对象的hash值,每次先锁的对象都是传进来的对象取identityHashCode方法算出来的值小的,后锁的都是大的。(这样可以写出来一个if else),如果出现hash冲突,就再设置一个自己定义的static的锁对象,先用这把static锁锁住保证只有一个线程进入该方法的顺序锁阶段,随后随便设定锁入参a,b即可,因为你保证了只有一个线程操作这个阶段。
private static Object tieLock = new Object();
public void deadLockTest(Object a, Object b) {
int hashA = System.identityHashCode(a);
int hashB = System.identityHashCode(b);
if (hashA < hashB) {
synchronized (a) {
System.out.println("锁住了小的准备获取大的");
synchronized (b) {
System.out.println("获取到了hash大的");
}
}
} else if (hashB < hashA) {
synchronized (b) {
System.out.println("锁住了小的准备获取大的");
synchronized (a) {
System.out.println("获取到了hash大的");
}
}
} else {
synchronized (tieLock){
synchronized (a){
synchronized (b){
}
}
}
}
}
解决办法2:
使用显示锁里的trylock方法,得不到锁的话就进行释放
标签:顺序,java,synchronized,对象,System,锁住,死锁,线程 来源: https://blog.csdn.net/weixin_48445640/article/details/116565223