Java 让线程A块B&;C,反之亦然,但不要让线程B阻塞线程C,反之亦然?

Java 让线程A块B&;C,反之亦然,但不要让线程B阻塞线程C,反之亦然?,java,multithreading,concurrency,locking,Java,Multithreading,Concurrency,Locking,我有一个问题,我有一个数据结构和多个线程试图对其进行操作。尽可能简单地说:我有线程A、B和C。只要B和C不对数据集进行任何更改,线程A只能执行其操作。不过,B和C可以在大多数情况下同时在机组上运行。因此,目标是: 螺纹A块B&C 螺纹B&C块A 螺纹B不阻塞C(反之亦然) 问题是,我如何才能做到这一点? 我希望我想做的事情很清楚。如果没有,请随意评论。我故意不提供任何代码,因为我认为这样更容易理解问题(很多长代码)。您需要使对象线程安全 简言之,你必须: 让你的领域成为私人领域 找到您的关键

我有一个问题,我有一个数据结构和多个线程试图对其进行操作。尽可能简单地说:我有线程A、B和C。只要B和C不对数据集进行任何更改,线程A只能执行其操作。不过,B和C可以在大多数情况下同时在机组上运行。因此,目标是:

  • 螺纹A块B&C
  • 螺纹B&C块A
  • 螺纹B不阻塞C(反之亦然)
问题是,我如何才能做到这一点?
我希望我想做的事情很清楚。如果没有,请随意评论。我故意不提供任何代码,因为我认为这样更容易理解问题(很多长代码)。

您需要使对象线程安全

简言之,你必须:

  • 让你的领域成为私人领域
  • 找到您的关键部分,并使用
    synchronized
    bloc保护它们
  • 在这篇文章中,你可以很好地恢复这个概念,并解释其他方法


    一旦您的字段在基本CRUD操作(创建、读取、更新、删除)上得到正确保护,您就可以使用特定方法专门读取线程B和C的数据,以及线程A的其他数据

    您可以使用

    您想要使用具有两个许可证的信号量

    您的A线程将始终请求两个许可证(获取(2))

    您的B和C线程将只要求一个许可证(acquire())

    这样,B和C总是可以一起工作,A将阻止B或C(因为没有可用的许可证)。B或C将阻止A,因为只剩下一个许可证

    它将适用于任何已知数量的(B,C)线程,因为信号量可以设置为这个数量。主要问题是,如果B和C总是获得一个许可证,那么A可能会饿死。
    因此,如果N=nr(B)+nr(C),那么任何A型螺纹都需要(N)。它不适用于未知数量的B、C,因为信号量允许数量不能动态增加。

    您将始终同时有3个线程,还是可能有多个线程@Phil@TimoH大多数情况下会有超过3个线程。例如,1个线程执行A操作,9个线程执行B或C操作。这意味着总有一个像A这样的线程,它只能在没有其他线程运行的情况下运行,但可以有任意数量的其他线程,它可以并行运行。我想您需要另一个类来充当信号量,以帮助协调线程何时应该处理或不应该处理。我不太理解您在最后一句话的后半部分中的意思。其余的我都很清楚,这不是大问题,谢谢。如果有多个读者,只有一个作者,这对我来说是有意义的。然而,在我的例子中,多个线程(示例中的B&C)可以同时写入(只要它们正在更改的元素不同),但A是读卡器,只有在B和C没有进行任何更改的情况下才能读取。这个可重入的TreadWriteLock是否也适用于这个概念?@Phil您的线程实际上正在执行读/写操作并不重要。B,C将接受读锁(即使他们执行写操作),因为它不是独占的,而A接受写锁,因为这会阻止任何其他访问。@菲尔,线程无法知道操作是“读”还是“写”。@Zielu谢谢,在这种情况下,这将按照我的需要工作@除非你在答案中添加更多的单词(代码)。即使它是正确的并且对作者有效,它也很可能会被作为LinkOnly删除。我认为如果他只使用3个线程,这将是正确的解决方案,但是我认为如果他有多个线程做A的工作,并且B+CIt工作,只要所有的A线程都需要N个许可证,其中N=数量(B+C),这将不起作用。如果事先不知道这些数字,这是行不通的。@Zielou-Yep。但如果他动态地生成线程,我想它会变得更复杂。例如N=B+C=2,A尝试获取N=2的信号量,因此aquire(2),现在D加入环,具有与B+C相同的权限,因此N=3,但A尝试获取N=2的信号量。希望是这样clear@TimoH谢谢你们。正如我所想的那样,这同样有效。为了学习,我可能也会尝试一下。不过,我现在确实使用了ReentrantReadWriteLock,它工作得很好,非常感谢!