【问题标题】:Improving concurrency in a multithreading example在多线程示例中提高并发性
【发布时间】:2013-03-19 14:20:24
【问题描述】:

锁定机制 - 每个方法都运行一个队列,用于跟踪该方法正在处理的进程内密钥。

    private final static Object LOCK = new Object();
    private final static Set<String> busy1Records = new HashSet<String>();
    private final static Set<String> busy2Records = new HashSet<String>();

    public void waitToWorkOn(int i, String key) {
        synchronized(LOCK) {

          switch(i) {
            case 1 : while (busy1Records.contains(key)) {
                        LOCK.wait(); //go to sleep
                     }
                     busy1Records.add(key);  
                     break;
            case 2 : while (busy2Records.contains(key)) {
                     LOCK.wait(); //go to sleep
                     }
                     busy2Records.add(key);  
                     break;
          }//end switch

       } // end sychronized                    
    }


    public void doneWith(int i, String key) {
        synchronized(LOCK) {

        switch(i) { 

          case 1:
              busy1Records.remove(key);
              LOCK.notifyAll(); 
              break;
          case 2:
              busy2Records.remove(key);
              LOCK.notifyAll(); 
              break;

        }

要使用这些 Sets ,该类中有这些方法。

private void method1(String key) {

try {

waitToWorkOn(1,key);
// Do stuffs here for key   

}catch(Exception e)  {..}
finally {
doneWith(1,key);
}

}

private void method2(String key) {

try {

waitToWorkOn(2,key);    
// Do stuffs here for key

}catch(Exception e)  {..}
finally {
doneWith(2,key);
}

}

考虑有 3 个线程 [每个线程都在这个类的一个新实例上工作]

T1 - key = X
T2 - key = X
T3 - key = Z

所以当 T1 在 method1 中时,它会获取 LOCK 并将 key 添加到 method1 的队列中并释放 LOCK。但是它还没有调用 doneWith 方法,然后另一个线程 T2 尝试插入相同的实体 X。所以它在 waitToWorkON 中获取 LOCK 并且因为它发现 X 已经在 Queue1 中,所以它必须在里面等待。然后一个线程 T3 来了,它必须在独立于 X 的第三个实体 Z 上调用方法 1。但是它无法获取 LOCK,因为 T2 正在等待并持有 LOCK。

如何让 T3 继续执行 Z 的方法 1 而无需等待 T2 在 X 上等待? T1 还没有从 Queue 中释放 X。

【问题讨论】:

  • 这让我很困惑。你能简单地告诉我你想达到什么目标吗?
  • 我希望一个线程只有在处理相同的密钥时才应该等待另一个线程。否则它们应该同时运行。 T2 等待 T1 并遵循此规则,但 T3 也等待 T2 .. 我需要避免第二种情况,因为它们在不同的键上工作。
  • 为什么你把两套锁在一起?
  • @fortm LOCK.wait() 释放锁,当wait 返回时重新获取。所以是的,如果线程 1 正在等待,线程 2 可以进入同步块。
  • 好的,我明白你想要达到的目标。是的,当锁调用等待时,它会释放锁并且线程进入等待队列,直到它发出信号。之后,线程移动到就绪队列并 WAITs 重新获取锁。

标签: java multithreading


【解决方案1】:

感谢@Hamlet 和@assylias 的回答

@fortm LOCK.wait() 释放锁,等待返回时重新获取。所以是的,如果线程 1 正在等待,线程 2 可以进入同步块。 – assylias 21 分钟前 1 票赞成

好的,我了解您想要实现的目标。是的,当锁调用等待时, 它释放锁,线程进入等待队列,直到它 发出信号。之后,线程移动到就绪队列并等待 重新获得锁。 – Hamlet Hakobyan 2 分钟前

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    相关资源
    最近更新 更多