【问题标题】:Conditional code synchronization only for specific threads仅针对特定线程的条件代码同步
【发布时间】:2013-11-30 21:21:34
【问题描述】:

假设有三组线程。让我们说 A、B 和 C。

我想在 A 和 B 类型线程之间发生阻塞的方法中创建代码块,在包括阻塞部分在内的方法调用的所有情况下都允许 C 线程。

换句话说,如果 A 类型的线程在阻塞的代码部分,B 被阻塞但 C 没有被阻塞。

您知道是否可以这样做吗?如果是这样,如何做到这一点?

【问题讨论】:

  • 你这样做的原因是什么?
  • 听起来是个坏主意。锁不仅是为了互斥;它们还提供了确保跨线程可见性的内存屏障。如果 C 组线程与 A 和 B 线程共享任何数据,您仍然需要一个内存屏障。如果您真正需要的是ReadWriteLock,我不会感到惊讶。
  • 我的问题与实际案例问题无关,而是我将来可能遇到的可能情况。
  • 你不会遇到这个问题。锁要么需要为所有线程发生,要么根本不需要发生,因为锁的目的是防止多重访问。有意义的是读/写锁之类的东西,因此是基于使用情况的锁定。

标签: java multithreading blocking nonblocking


【解决方案1】:

你可以有辅助锁定方法:

private final ReentrantLock mLock = new ReentrantLock();

void conditionalLock() {
    ThreadGroup group = Thread.currentThread().getThreadGroup();
    if (group.equals(groupA) || group.equals(groupB)) {
        mLock.lock();
    }
}

编辑更改/简化条件,正如 erickson 所建议的那样

void conditionalUnlock() {
    if (mLock.isHeldByCurrentThread()) {
        mLock.unlock();
    }
}

那么,在同一个类的方法中:

    conditionalLock();
    try {
        // block you want to synchronize between threads of group A & B
    } finally {
        conditionalUnlock();
    }

【讨论】:

  • A、B 与 C 的区别是什么?
  • if 块中传递什么?
  • conditionalUnlock()中,我建议测试是否锁定isHeldByCurrentThread(),而不是再看组。
  • @erickson 完全有道理,谢谢,我会更新代码
【解决方案2】:

也许那是一种丑陋的做法,但我有一个想法。

您可以命名您的 Threads 并执行 if 语句检查名称(线程类型)。

if (Thread.currentThread().getName().contains("A") || Thread.currentThread().getName().contains("B")){
    synchronized(this){
        //do stuff
    }
}else{
    //do stuff or even check if its type C
}

【讨论】:

  • 如果线程按名称分组,则您的解决方案是正确的。但是 kiruwka 的解决方案更通用。
  • 是的,它更通用,我同意。 :)
  • 好吧,老实说,我认为我的方法和您的答案之间没有显着差异,除了您必须复制代码块 //do stuff。所以也给你+1。
  • @mmc18 谢谢。顺便说一句,没有冒犯,但我认为您可以将问题的标题重新表述得更具体,例如“仅针对特定线程的条件代码同步”。 “阻塞/解除阻塞”似乎是指一个有点不同的概念
  • 你是对的,即使我几乎找不到标题和问题之间的关系,我已经改变了它,现在现在的标题更有意义。
猜你喜欢
  • 2022-01-07
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
  • 2020-09-28
  • 2017-09-27
  • 2011-08-27
  • 1970-01-01
  • 2017-10-20
相关资源
最近更新 更多