Java 有没有一种方法可以以原子方式锁定2个或多个锁或监视器?
有没有一种方法可以以原子方式锁定2个或多个锁或监视器?我的意思是,假设我的线程希望锁定两个锁,并等待它们都空闲,即从不锁定一个然后等待另一个?我认为这相当于吃饭哲学家的问题-访问可以为您提供指向几种可能的解决方案的指针Java 有没有一种方法可以以原子方式锁定2个或多个锁或监视器?,java,concurrency,locking,critical-section,Java,Concurrency,Locking,Critical Section,有没有一种方法可以以原子方式锁定2个或多个锁或监视器?我的意思是,假设我的线程希望锁定两个锁,并等待它们都空闲,即从不锁定一个然后等待另一个?我认为这相当于吃饭哲学家的问题-访问可以为您提供指向几种可能的解决方案的指针 干杯,没有办法以原子方式获取多个监视器 锁系统可以设计成做类似的事情,尽管效率很低 如果没有关于用例的更多信息,就很难规定任何潜在的解决方案,但是有一种模式允许安全地获取多个锁,而不会出现死锁 我知道这不是你想要的,我很乐意为你指出一个更好的方向和更多的细节,但如果你唯一的愿望是
干杯,没有办法以原子方式获取多个监视器 锁系统可以设计成做类似的事情,尽管效率很低 如果没有关于用例的更多信息,就很难规定任何潜在的解决方案,但是有一种模式允许安全地获取多个锁,而不会出现死锁 我知道这不是你想要的,我很乐意为你指出一个更好的方向和更多的细节,但如果你唯一的愿望是避免僵局,那么就这样做:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LockSort{
private int ptr = 0;
private final Object[] locks;
private final Runnable toRun;
private LockSort(Runnable r, Object[] l){
locks = l;
Arrays.sort(locks, identCompare);
toRun = r;
}
private static final Comparator<Object> identCompare = new Comparator<Object>(){
@Override
public int compare(Object a, Object b){
return System.identityHashCode(a) - System.identityHashCode(b);
}
};
private void lockSingle(){
synchronized(locks[ptr++]){
dispatch();
}
}
private static final Map<Integer, MutableInteger> breakers = new HashMap<>();
private static MutableInteger getTieBreaker(Integer hash){
synchronized(breakers){
MutableInteger b = breakers.get(hash);
if(null != b){
b.val++;
return b;
}
breakers.put(hash, b = new MutableInteger(1));
return b;
}
}
private static void releaseTieBreaker(Integer hash){
synchronized(breakers){
MutableInteger b = breakers.get(hash);
if(0 == --b.val)
breakers.remove(hash);
}
}
private void breakTie(){
final Integer hash = System.identityHashCode(locks[ptr]);
try{
synchronized(getTieBreaker(hash)){
synchronized(locks[ptr++]){
dispatch();
}
}
}finally{
releaseTieBreaker(hash);
}
}
private void dispatch(){
if(ptr == locks.length)
toRun.run();
else if(ptr + 1 == locks.length || System.identityHashCode(locks[ptr]) != System.identityHashCode(locks[ptr + 1]))
lockSingle();
else
breakTie();
} import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LockSort{
private int ptr = 0;
private final Object[] locks;
private final Runnable toRun;
private LockSort(Runnable r, Object[] l){
locks = l;
Arrays.sort(locks, identCompare);
toRun = r;
}
private static final Comparator<Object> identCompare = new Comparator<Object>(){
@Override import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LockSort{
private int ptr = 0;
private final Object[] locks;
private final Runnable toRun;
private LockSort(Runnable r, Object[] l){
locks = l;
Arrays.sort(locks, identCompare);
toRun = r;
}
private static final Comparator<Object> identCompare = new Comparator<Object>(){
@Override
public int compare(Object a, Object b){
return System.identityHashCode(a) - System.identityHashCode(b);
}
};
private void lockSingle(){
synchronized(locks[ptr++]){
dispatch();
}
}
private static final Map<Integer, MutableInteger> breakers = new HashMap<>();
private static MutableInteger getTieBreaker(Integer hash){
synchronized(breakers){
MutableInteger b = breakers.get(hash);
if(null != b){
b.val++;
return b;
}
breakers.put(hash, b = new MutableInteger(1));
return b;
}
}
private static void releaseTieBreaker(Integer hash){
synchronized(breakers){
MutableInteger b = breakers.get(hash);
if(0 == --b.val)
breakers.remove(hash);
}
}
private void breakTie(){
final Integer hash = System.identityHashCode(locks[ptr]);
try{
synchronized(getTieBreaker(hash)){
synchronized(locks[ptr++]){
dispatch();
}
}
}finally{
releaseTieBreaker(hash);
}
}
private void dispatch(){
if(ptr == locks.length)
toRun.run();
else if(ptr + 1 == locks.length || System.identityHashCode(locks[ptr]) != System.identityHashCode(locks[ptr + 1]))
lockSingle();
else
breakTie();
}
public static void lockMultipleAndRun(Runnable toRun, Object... toLock){
new LockSort(toRun, toLock).dispatch();
}
public static void lockMultipleAndRun(Runnable toRun, Collection<Object> toLock){
new LockSort(toRun, toLock.toArray()).dispatch();
}
private static class MutableInteger{
int val;
MutableInteger(int i){
val = i;
}
}
public static void main(String args[]){
final int THREADS = 0 == args.length ? Runtime.getRuntime().availableProcessors() : Integer.valueOf(args[0]);
for(int j = 0; j < 1000; j++){
final int RUNID = j;
final Object locks[] = new Object[300];
for(int i = 0; i < 300; i++){
locks[i] = new Object(){
};
}
List<Thread> threads = new ArrayList<>(50);
for(int i = 0; i < THREADS; i++){
final int ID = i;
Thread t = new Thread(new Runnable(){
@Override
public void run(){
for(int i = 0; i < 1000; i++){
int a = (int) Math.floor(Math.random() * 300.0);
int b = (int) Math.floor(Math.random() * 300.0);
final int l = Math.min(a, b);
final int h = Math.max(a, b);
final int CT = i;
lockMultipleAndRun(new Runnable(){
@Override
public void run(){
System.out.println(RUNID + ":" + ID + " @ " + CT + " w/ " + l + "-" + h);
}
}, Arrays.copyOfRange(locks, l, h));
}
}
});
t.start();
threads.add(t);
}
for(Thread t : threads){
try{
t.join();
}catch(InterruptedException e){
throw new RuntimeException(e);
}
}
}
}
}
public int compare(Object a, Object b){
return System.identityHashCode(a) - System.identityHashCode(b);
}
};
private void lockSingle(){
synchronized(locks[ptr++]){
dispatch();
}
}
private static final Map<Integer, MutableInteger> breakers = new HashMap<>();
private static MutableInteger getTieBreaker(Integer hash){
synchronized(breakers){
MutableInteger b = breakers.get(hash);
if(null != b){
b.val++;
return b;
}
breakers.put(hash, b = new MutableInteger(1));
return b;
}
}
private static void releaseTieBreaker(Integer hash){
synchronized(breakers){
MutableInteger b = breakers.get(hash);
if(0 == --b.val)
breakers.remove(hash);
}
}
private void breakTie(){
final Integer hash = System.identityHashCode(locks[ptr]);
try{
synchronized(getTieBreaker(hash)){
synchronized(locks[ptr++]){
dispatch();
}
}
}finally{
releaseTieBreaker(hash);
}
}
private void dispatch(){
if(ptr == locks.length)
toRun.run();
else if(ptr + 1 == locks.length || System.identityHashCode(locks[ptr]) != System.identityHashCode(locks[ptr + 1]))
lockSingle();
else
breakTie();
}
public static void lockMultipleAndRun(Runnable toRun, Object... toLock){
new LockSort(toRun, toLock).dispatch();
}
public static void lockMultipleAndRun(Runnable toRun, Collection<Object> toLock){
new LockSort(toRun, toLock.toArray()).dispatch();
}
private static class MutableInteger{
int val;
MutableInteger(int i){
val = i;
}
}
public static void main(String args[]){
final int THREADS = 0 == args.length ? Runtime.getRuntime().availableProcessors() : Integer.valueOf(args[0]);
for(int j = 0; j < 1000; j++){
final int RUNID = j;
final Object locks[] = new Object[300];
for(int i = 0; i < 300; i++){
locks[i] = new Object(){
};
}
List<Thread> threads = new ArrayList<>(50);
for(int i = 0; i < THREADS; i++){
final int ID = i;
Thread t = new Thread(new Runnable(){
@Override
public void run(){
for(int i = 0; i < 1000; i++){
int a = (int) Math.floor(Math.random() * 300.0);
int b = (int) Math.floor(Math.random() * 300.0);
final int l = Math.min(a, b);
final int h = Math.max(a, b);
final int CT = i;
lockMultipleAndRun(new Runnable(){
@Override
public void run(){
System.out.println(RUNID + ":" + ID + " @ " + CT + " w/ " + l + "-" + h);
}
}, Arrays.copyOfRange(locks, l, h));
}
}
});
t.start();
threads.add(t);
}
for(Thread t : threads){
try{
t.join();
}catch(InterruptedException e){
throw new RuntimeException(e);
}
}
}
}
}
public static void lockMultipleAndRun(Runnable toRun, Object... toLock){
new LockSort(toRun, toLock).dispatch();
}
public static void lockMultipleAndRun(Runnable toRun, Collection<Object> toLock){
new LockSort(toRun, toLock.toArray()).dispatch();
}
private static class MutableInteger{
int val;
MutableInteger(int i){
val = i;
}
}
public static void main(String args[]){
final int THREADS = 0 == args.length ? Runtime.getRuntime().availableProcessors() : Integer.valueOf(args[0]);
for(int j = 0; j < 1000; j++){
final int RUNID = j;
final Object locks[] = new Object[300];
for(int i = 0; i < 300; i++){
locks[i] = new Object(){
};
}
List<Thread> threads = new ArrayList<>(50);
for(int i = 0; i < THREADS; i++){
// Shuffle the locks per-thread to see more highly chaotic and difficult to deal with locking behavior
final Object[] myLocks = new Object[300];
System.arraycopy(locks, 0, myLocks, 0, 300);
for(int k = 0; k < 300; k++){
int a = (int) Math.floor(Math.random() * 300.0);
int b = (int) Math.floor(Math.random() * 300.0);
Object o = myLocks[a];
myLocks[a] = myLocks[b];
myLocks[b] = o;
}
final int ID = i;
Thread t = new Thread(new Runnable(){
@Override
public void run(){
for(int i = 0; i < 1000; i++){
int a = (int) Math.floor(Math.random() * 300.0);
int b = (int) Math.floor(Math.random() * 300.0);
final int l = Math.min(a, b);
final int h = Math.max(a, b);
final int CT = i;
lockMultipleAndRun(new Runnable(){
@Override
public void run(){
System.out.println(RUNID + ":" + ID + " @ " + CT + " w/ " + l + "-" + h);
}
}, Arrays.copyOfRange(locks, l, h));
}
}
});
t.start();
threads.add(t);
}
for(Thread t : threads){
try{
t.join();
}catch(InterruptedException e){
throw new RuntimeException(e);
}
}
}
}
}
import java.util.ArrayList;
导入java.util.array;
导入java.util.Collection;
导入java.util.Comparator;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
公共类锁排序{
私有整数ptr=0;
私有最终对象[]锁;
私人最终可运行的toRun;
私有锁排序(可运行的r,对象[]l){
锁=l;
数组。排序(锁、标识比较);
toRun=r;
}
私有静态最终比较器identCompare=新比较器(){
@凌驾
公共整数比较(对象a、对象b){
返回系统识别码(a)-系统识别码(b);
}
};
私有无效锁单(){
已同步(锁定[ptr++]){
分派();
}
}
private static final Map breaker=new HashMap();
私有静态可变整数getTiebarker(整数散列){
同步(断路器){
MutableInteger b=breakers.get(散列);
if(null!=b){
b、 val++;
返回b;
}
put(散列,b=新的可变整数(1));
返回b;
}
}
私有静态void releaseTieBreaker(整数散列){
同步(断路器){
MutableInteger b=breakers.get(散列);
如果(0==--b.val)
删除(散列);
}
}
私人空位中断(){
最终整数散列=System.identityHashCode(锁[ptr]);
试一试{
已同步(gettiebarker(散列)){
已同步(锁定[ptr++]){
分派();
}
}
}最后{
releaseTieBreaker(散列);
}
}
私密{
if(ptr==locks.length)
toRun.run();
else if(ptr+1==locks.length | | System.identityHashCode(locks[ptr])!=System.identityHashCode(locks[ptr+1]))
锁单();
其他的
领带();
}导入java.util.ArrayList;
导入java.util.array;
导入java.util.Collection;
导入java.util.Comparator;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
公共类锁排序{
私有整数ptr=0;
私有最终对象[]锁;
私人最终可运行的toRun;
私有锁排序(可运行的r,对象[]l){
锁=l;
数组。排序(锁、标识比较);
toRun=r;
}
私有静态最终比较器identCompare=新比较器(){
@覆盖导入java.util.ArrayList;
导入java.util.array;
导入java.util.Collection;
导入java.util.Comparator;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
公共类锁排序{
私有整数ptr=0;
私有最终对象[]锁;
私人最终可运行的toRun;
私有锁排序(可运行的r,对象[]l){
锁=l;
数组。排序(锁、标识比较);
toRun=r;
}
私有静态最终比较器identCompare=新比较器(){
@凌驾
公共整数比较(对象a、对象b){
返回系统识别码(a)-系统识别码(b);
}
};
私有无效锁单(){
已同步(锁定[ptr++]){
分派();
}
}
private static final Map breaker=new HashMap();
私有静态可变整数getTiebarker(整数散列){
同步(断路器){
MutableInteger b=breakers.get(散列);
if(null!=b){
b、 val++;
返回b;
}
put(散列,b=新的可变整数(1));
返回b;
}
}
私有静态void releaseTieBreaker(整数散列){
同步(断路器){
MutableInteger b=breakers.get(散列);
如果(0==--b.val)
删除(散列);
}
}
私人空位中断(){
最终整数散列=System.identityHashCode(锁[ptr]);
试一试{
已同步(gettiebarker(散列)){
已同步(锁定[ptr++]){
分派();
}
}
}最后{
releaseTieBreaker(散列);
}
}
私密{
if(ptr==locks.length)
toRun.run();
else if(ptr+1==locks.length | | System.identityHashCode(locks[ptr])!=System.identityHashCode(locks[ptr+1]))
锁单();
其他的
领带();
}
公共静态无效锁MultipleAndRun(可运行的toRun、对象…toLock){
新的锁排序(toRun,toLock).dispatch();
}
公共静态无效锁MultipleAndRun(可运行的toRun、集合toLock){
新的锁排序(toRun、toLock.toArray()).dispatch();
}
私有静态类MutableInteger{
int-val;
可变整数(int i){
val=i;
}
}
公共静态void main(字符串参数[]){
final int THREADS=0==args.length?Runtime.getRuntime().availableProcessors():Integer.valueOf(args[0]);
对于(int j=0;j<1000;j++){
最终int-RUNID=j;
最终对象锁[]=新对象[300];
对于(int i=0;i<300;i++){
locks[i]=新对象(){
};
}
列表线程=新的ArrayList(50);
对于(int i=0;isynchronized (l_extra) {
synchronized (l_0) {
synchronized (l_1) {
// ...
}
}
}