问题标签 [reentrantlock]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Java中的嵌套监视器
如果我在 Java 中使用 ReentrantLock ...当一个线程拥有一个对象的锁并尝试获取另一个对象的另一个锁时,它是释放第一个锁还是仍然持有它?
java - ReentrantLock 不起作用
我无法弄清楚为什么代码不能正常工作。问题是 ReentrantLock 不会锁定 ThreadClass.run() 中的方法调用
资源类,哪些方法被假定在 ThreadClass 中被锁定
线程类
主班
假设 run() 中被 lock 包围的代码必须是“同步的”,从而导致只有一个线程可以访问资源对象的方法。在实践中它没有。代码结果重复数字,这意味着两个线程可以同时访问这些方法。我知道这是一个非常简单的问题,但我不明白如何解决它。感谢您的帮助。
更新:
收到。那段代码工作得很好(我删除了 setIncrement() 并将所有相关逻辑放入 getIncrement()):
java - Java ReentrantLock 和条件 | 生产者完成工作,消费者陷入困境
一般信息: 三个读取器线程以块的形式从文件中随机读取,其中每个块都有一个 ID,并且它们写入普通的 ArrayList。只要将具有所需 ID 的块添加到列表中,写入器线程就会写入输出文件。
出于这个原因,我编写了一个 BlockingChunkList,它应该同步 add() 和 getNextChunk() 方法。
它适用于我在一种情况下使用同步 + 通知 + notifyAll 和在另一种情况下使用同步列表。
当我使用 ReentrantLock 和 Condition 时,我无法做到这一点。writer-thread 只写了四个块,然后他就卡住了。
为什么它可能不起作用: 我怀疑一旦阅读器完成,作者就无法取回锁。但是我希望每次有东西要写(available = true)时,都应该调用写线程。当 available 为真时,他们似乎忽略了 hasAccess.await() 。
它应该如何工作: 读取线程仅调用 add 方法,并且仅在有要写入的内容(可用)时才释放写入线程。当 available=true 时,它们也会阻止自己。当作者通过调用 hasAccess.signalAll() 写了一些东西时,这个锁被释放。写线程只调用 getNextChunk() 方法,他在写块时释放其他线程。当 available=false 时,他会阻止自己,并被读者释放。
问题: 读取线程完成工作,写入线程只写入前 4 个块。我希望编写器总是在available=true 时被调用。
我不需要一个确切的解决方案,因为我认为我遗漏了一些东西,所以也很感激提示。所以:我错过了什么?
谢谢你
编辑:并发仅在发布的类中处理。主要方法仅启动踏板。编辑 2:这是我第一次尝试并发。我知道 ArrayList 不是线程安全的。我想通过使用 ReentrantLock 和 Condition 来理解这些概念。BASIC的想法是阻止读取器或写入器,无论可用是真还是假。
解决方案: 处理线程没有任何问题。事实证明这是我这边的一个逻辑错误。写入线程卡住了,因为他没有机会检查必要的 ID,因为写入者随机读取块。感谢您的帮助。
java - Java,锁,条件 - 信号未唤醒等待线程
我有一个问题,我被困了几个小时,我真的不知道如何解决它。这很简单——我有一些线程,其中一个需要等待来自另一个的信号。不知何故,即使我在某个条件下发出信号……什么也没有发生!看起来线程仍在休眠。这真是一个奇怪的问题,但我不太了解某些东西可能是我的错......
这是我的代码的一部分:
我确信 body.signalAll(); 当有线程在该条件下等待时调用 - 我检查并调试器多次遍历该行。然而,“我在等待”这句话只出现一次,“我醒来”从未出现过。
任何想法,如何解决它,或检查什么?我几乎尝试了所有...
感谢您的时间和帮助!
java - 多个条件与多个锁
对于特定的线程安全数据结构,我需要保护对中央数据结构(即字节数组)的访问。在这种情况下,我选择使用 ReentrantLocks 是因为它的公平策略以及创建多个条件的高级功能。
并发的条件比较复杂,列举如下:
- 必须专门保护中央字节数组(即一次一个线程)。
- 两种访问方法(foo 和 bar)必须能够同时运行(如果它们试图访问中央字节数组,则会在内部阻塞)。
- 对任何方法(foo 和 bar)的调用必须是独占的(即从不同线程多次调用 foo 将导致一个线程阻塞)。
在我最初的实现中,我选择实现两个嵌套锁,如下所示:
该结构在方法上是等价的bar
,只是带有另一个锁对象lockBar
。此外,为简单起见,该代码已将我更复杂的多条件等待和信号减少为单个条件。
使用它,我不禁觉得代码似乎不必要地复杂和晦涩,因为不仅嵌套了两个锁,它们共享一个 try-finally,更不用说如何在整个过程中lockCentral
被释放和重新获取多次lockFoo
.
相反,我尝试重新组织外部锁(lockFoo
和lockBar
)作为lockCentral
代替的条件,如下所示:
经过一番检查,我无法决定前者是更好的主意还是后者(尤其是包含该随机布尔值)。简化代码的想法似乎导致代码更长,在这种情况下非常违反直觉。
是否有一些约定或令人信服的理由来论证:
每个锁定上下文使用一个锁(前一个代码,锁定的不同原因共享不同的锁)。
每个锁定资源使用一个锁(后一种代码,要保护的中央结构使用单个锁,其他所有内容都作为访问所述结构的条件实现)。
java - 在一个类中有两个 ReentrantLock 有什么好处?
如果我有这个代码:
和有什么区别lock1
,lock2
是简单的别名还是有不同的逻辑?
java - 使用 ReentrantLock 而不是同步的好处
我发现使用 ReentrantLock 而不是同步的另一个好处
下面的代码显示即使在临界区锁被释放时发生异常(使用 ReentrantLock )
现在通过使用同步
通过比较这两个代码,我发现使用同步块还有一个缺点,即如果在关键部分发生异常,则无法释放锁。
我对吗 ?
如果我错了,请纠正我。
如果同步块中发生异常,是否有释放锁?
java - Java中线程之间的无锁通信
所以我想要实现的是两个线程轮流执行他们的任务。我最初只有一个问题;
- 如何在不使用锁的情况下实现两个线程轮流执行任务?我不想要锁的原因是因为我感觉很愚蠢,当两个线程试图访问没有公共资源时使用锁。
所以我打算做一个代码的小例子,然后我发现我无法让它工作,即使有锁。所以我的第二个问题是;如何使代码按预期工作?我看到它的方式,它应该工作,但这只是我:)
- Thread1 打印消息
- Thread1 表示 Thread2 可以打印消息
- Thread2 打印消息
- Thread2 表示 Thread1 可以重新开始
java - 线程获取了已经被其他线程获取的 ReentrantLock
我们的应用程序在 WebLogic 12c 中运行,正在从队列系统中检索消息,我们从中检索消息的队列被配置为 FIFO。我们使用 Spring 来配置检索功能,并且容器 (org.springframework.jms.listener.DefaultMessageListenerContainer) 和消息侦听器 (org.springframework.jms.core.support.JmsGatewaySupport) 都是单例的。此外,该容器默认配置了一个 WorkManager 作为任务执行器。为了保证消息按照预期的顺序(它们发送到队列的顺序)进行处理,我们在监听器中使用了 ReentrantLock,我们期望消息被一一检索和处理。监听器代码如下:
即使两条消息以正确的顺序放置在队列中,并且按该顺序被消费(回想一下队列是一个 FIFO 队列),但不知何故,这两条消息由应用程序并行处理,如下所示日志块:
为什么我们会获得这种行为?任何想法?
非常感谢您。
java - Java中队列中线程的执行
我有这个练习:
开发一个多线程应用程序。使用 java.util.concurrent 机会。
不要使用:同步、BlockingQueue、BlockingDeque
所有希望访问资源的实体都必须是线程。利用 OOP 的机会。
我的任务是:
免费收银台。快餐店有几个收银台。客户在特定收银台排队,但如果那里的队列减少或消失,可能会去另一个收银台。
这是我的解决方案https://github.com/NikitaMitroshin/FreeCash
客户端代码:
收银台代码:
跑步者代码:
我有问题。这就是我运行我的应用程序后得到的
因此,如您所见,服务队列受到干扰。
当为 client3 提供服务时,client6 必须开始服务,但 client50 这样做。当客户端 5 被服务时,客户端 4 必须开始服务,但客户端 7 这样做。当 client7 服务时,我不知道为什么,但是 client6 移动到 cashDesk#1 并开始服务,尽管 client4 必须开始服务。
我是多线程新手,所以我需要一个建议,如何让我的应用程序正常工作