建议锁定样品盒

时间:2013-02-27 05:32:28

标签: java multithreading

2个线程从GenericObjectPool声明2个可重用实例,并开始处理以下数据集resp -

Thread 1 [ Rec1, Rec1, Rec2 ]

Thread 2 [ Rec1, Rec3, Rec2 ]

Thread 3 [ Rec3 ]

首先要查找这些记录,如果没有找到,则只插入一组表格中。因此,在thread1中, Rec1 两次出现时会按顺序运行安全处理。 但是,由于跨越实例存在争用,因为来自Pool的第二个实例上的Thread2也具有 Rec1 。类似于Rec2,Rec3也会重复。所以,我将锁定为静态最终...

课程本身就是这样 -

Method1
--------
loop on all records
check condition1 
If Meets
lock obj
Recheck condition1
if meets
INSERT1
release lock
end loop

而且..

Method 2
---------
loop on all records
check condition2 
If Meets
lock obj
Recheck condition2
if meets
INSERT2
release lock
end loop

关于“obj”锁定的建议?使其成为静态最终将解决它,但由于大量使用类级别锁定,使程序几乎是顺序的。

2 个答案:

答案 0 :(得分:1)

在执行操作时不要按住锁定。使用同步调用只是为了仲裁谁来处理什么记录,不在同步块内进行操作,并在完成时发出信号。

so(在java中):

private final static Object LOCK = new Object();
private final static Set<Integer> busyRecords = new HashSet<Integer>();

public static void waitToWorkOn(int recordNum) {
   synchronized(LOCK) {
      while (busyRecords.contains(recordNum)) {
         LOCK.wait(); //go to sleep
      }
      busyRecords.add(recordNum); //ours now
   }
}

public static void doneWith(int recordNum) {
   synchronized(LOCK) {
      busyRecords.remove(recordNum);
      LOCK.notifyAll(); //wake sleepers up
   }
}

任何使用它的代码都必须使用try-finally来确保发送释放信号:

waitToWorkOn(recordNum);
try {
   //do something to record
} finally {
   doneWith(recordNum);
}

答案 1 :(得分:1)

尝试使用java.util.concurrent.ConcurrentLinkedQueue而不是您自己的锁定机制。这是Simple, Fast, and Practical Non-Blocking

如果我理解你的问题,你需要分别为method1和method2提供两个不同的队列。此外,名为loop on all records的步骤也会定义为get element from queue or wait