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”锁定的建议?使其成为静态最终将解决它,但由于大量使用类级别锁定,使程序几乎是顺序的。
答案 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