Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有没有一种方法可以以原子方式锁定2个或多个锁或监视器?_Java_Concurrency_Locking_Critical Section - Fatal编程技术网

Java 有没有一种方法可以以原子方式锁定2个或多个锁或监视器?

Java 有没有一种方法可以以原子方式锁定2个或多个锁或监视器?,java,concurrency,locking,critical-section,Java,Concurrency,Locking,Critical Section,有没有一种方法可以以原子方式锁定2个或多个锁或监视器?我的意思是,假设我的线程希望锁定两个锁,并等待它们都空闲,即从不锁定一个然后等待另一个?我认为这相当于吃饭哲学家的问题-访问可以为您提供指向几种可能的解决方案的指针 干杯,没有办法以原子方式获取多个监视器 锁系统可以设计成做类似的事情,尽管效率很低 如果没有关于用例的更多信息,就很难规定任何潜在的解决方案,但是有一种模式允许安全地获取多个锁,而不会出现死锁 我知道这不是你想要的,我很乐意为你指出一个更好的方向和更多的细节,但如果你唯一的愿望是

有没有一种方法可以以原子方式锁定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) {
         // ...
      }
   }
}