【问题标题】:Suggested Lock for a sample case建议的锁示例
【发布时间】:2013-02-27 22:53:54
【问题描述】:

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

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”锁的建议?将其设置为 static final 将解决它,但由于广泛使用类级别锁定而使程序几乎是连续的..

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    在执行操作时不要持有锁。仅使用同步调用来仲裁谁可以处理哪些记录,不在同步块内执行操作,并在完成时发出信号。

    所以(在 ​​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);
    }
    

    【讨论】:

    • radai,由于这些线程在类的不同实例上工作,busyRecords 是一个成员变量,我想我需要将busyRecords 的范围也设为静态,以便所有运行的实例都可以看到繁忙的条目?
    • @fortm - set shold 也是静态的,我的错。我会解决的
    【解决方案2】:

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

    如果我理解你的问题,你需要分别为方法 1 和方法 2 设置两个不同的队列。此外,名为loop on all records 的步骤将被定义为类似get element from queue or wait

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-05
      • 2012-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多