问题标签 [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.

0 投票
2 回答
970 浏览

java - 如何正确确定锁的范围

假设我有一个ReentrantLock

以及bar使用锁的方法,

methodOne调用一个methodTwo也使用锁的方法,

bar在我打电话之前释放锁定会更好methodOne吗?一般来说,在调用另一个方法之前释放锁是一种好习惯吗?

0 投票
1 回答
234 浏览

java - 为什么 Java 锁实现中没有使用 synchronized 关键字?

synchronized在Java中用于处理互斥锁之类的事情。但是,Java 中的Lock接口实现ReentrantLock不使用 this 关键字。所有代码看起来都只是普通代码。那么它是如何处理地球上的多个线程的呢?

我相信以下代码片段是相关的:

中的tryAcquire方法SyncReentrantLock

Sync扩展AbstractQueuedSynchronizer和相关的代码:

所以似乎没有synchronized使用关键字,那么它如何保证互斥锁?

0 投票
1 回答
214 浏览

java - 没有公平性的延迟队列有问题吗?

在 Java 7 中,DelayQueue 的实现使用了没有公平策略的 ReentrantLock。从长远来看,这是一个问题吗?线程会因此而饿死吗?

谢谢

0 投票
2 回答
3487 浏览

java - 重入锁 - 尝试使用 rxtx 将字节 [] 写入串行端口时出现非法监视器状态异常

我有以下代码给我带来了很多麻烦,我想我已经盯着它太久了,新鲜的眼睛将不胜感激 -

调用方法 - (在 RobotInterface 类中)

TwoWaySerialCommTest 类 - 改编自 rxtx 网站示例。完整代码供参考,重要部分是 put() 方法和 serialwriter。

输出如下所示。我试过移动锁定文件,从串行写入器中取出锁,在调用方法中加锁以及其他一些技巧。

期望的结果是该方法将调用 serialConnection(已连接的 TwoWaySerialCommTest 的一个实例),并等待 serialConnection 写入串行端口并接收响应,然后再继续执行。

几个小时以来我一直在努力解决这个问题,请帮忙:)

如果我按照建议将通知移动到 try 块内,则输出为

RobotInterface 类 -

}

0 投票
2 回答
714 浏览

java - 为什么没有用 signalAll 激活等待线程?

我有2个功能。第一个 discoverHosts() 向其他计算机发送请求消息。在此之后,它使用 await 命令进入睡眠状态。一个单独的威胁在收到响应时调用 handleMessage() 函数。在他处理完响应后,他使用 notifyAll() 让 discoderHosts() 知道他必须检查是否收到了所有响应。

DiscoverHosts() 在调用该函数时会等待。但是,当单独的威胁调用handleMessage() 时,发现主机() 不会在handleMessage 调用signalAll() 时唤醒。我在调试时检查了是否调用了 signalAll(),就是这种情况。在我的项目的其他地方,我有几乎相同的代码。

你们中有人知道我在忽略什么吗?

记录器输出:

0 投票
1 回答
237 浏览

java - Java - 可重入锁,无法访问新创建的条件

我创建了一个新条件chopstickFree,在我的pickUpChopstick()方法中,我正在等待锁定它,但我根本无法访问它。

通过调试我发现当它到达方法中的chopstickFree.await()行时pickUpChopstick(),它只是无限期地暂停

我不明白?构造函数中的代码只是一个不确定的尝试让它工作,但无论哪种方式,我都创建了一个新条件,向所有人发出信号,它是免费的,但我根本无法锁定它?

有任何想法吗?

干杯

0 投票
5 回答
14976 浏览

java - 解锁另一个线程java拥有的锁

我有一个 LockManager 管理多个线程的锁。有时线程是坏孩子,我不得不杀死它们并要求 LockManager 释放它们所有的锁。但是,由于我在 java 中使用 ReentrantLock 这是不可能的,我无法解锁另一个线程拥有的锁。

我被迫使用锁(不能使用信号量,这是作业的重点)。是否有任何 Java Lock 实现允许我解锁其他线程拥有的锁?

到目前为止,我考虑的选项是:

  • 以允许我这样做的方式重新实现 ReentrantLock
  • 在信号量和可重入锁之间进行某种映射

您可能会发现有用的额外资源:

0 投票
1 回答
2348 浏览

java - ReentrantLock.tryLock(long timeout, TimeUnit unit) 获取不到锁时不超时

在我的项目与 Ehcache 集成期间(使用 BlockingCache 装饰器,它在内部使用 ReentrantLock)我在一台机器上发现了一些奇怪的行为。有时,等待通过 ReentrantLock.tryLock(timeout,TimeUnit) 获取锁的线程不会超时(结果为“假”)。JVM 将它们抛在脑后,它们一直处于阻塞状态,直到该锁被另一个线程释放。简而言之:有时 ReentrantLock.tryLock(long timeout, TimeUnit unit) 的行为类似于 ReentrantLock.lock()。

这种情况只发生在一台机器上,规格如下:

  • windows server 2003 R2 (5.2.3790 SP2 build 3790)
  • vmware esx 3.5
  • xeon x5675 (2x cpu x86 6 Model 44 Stepping 2 GenuineIntel)

我在 jre 1.6(1.6.0_31, 1.6.0_37) 上运行它

我在另外两台机器上测试过,效果很好(这个奇怪的问题不能在那里重现)。

这是我的测试代码:它启动第二个线程,该线程保持锁定 5 秒。主线程尝试获取它(timeout=50ms)。有时(在机器上进行 1000 次迭代,它会中断大约 14 次)主线程在 50 毫秒后不会超时,而是等到第二个线程释放锁(= 5 秒)。

感谢您的任何建议!

更新

这是阻塞机器的第二个测试:

}

输出是

0:203ms 1:203ms 2:203ms 3:203ms 4:203ms 5
2013 年 5 月 26 日星期日 10:36:22 EDT 2013 年 5月 26 日星期日
10:37:22 EDT 2013 5 5
月 26 日星期日 10:38:22 EDT 2013 .. .................... // 20 小时后(日志已在此处剪切) 2013 年 5 月 27 日星期一
06:00:26 EDT 2013 年 5
月 27 日星期一 06:01:26 EDT 2013 5
月 27 日星期一 06:02:26 EDT 2013 5
月 27 日星期一 06:03:26 EDT 2013

和线程转储:

2013-05-27 04:51:51 全线程转储 Java HotSpot(TM) 客户端 VM(20.6-b01 混合模式,共享):

“Thread-0”prio=6 tid=0x02b78400 nid=0xdf0 等待条件 [0x02ebf000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at TestLock2$1.run( TestLock2.java:26)

“内存不足检测器”守护进程 prio=6 tid=0x02b5a400 nid=0x218c 可运行 [0x00000000] java.lang.Thread.State: RUNNABLE

“C1 CompilerThread0”守护进程prio=10 tid=0x02b55400 nid=0x7a4 等待条件[0x00000000] java.lang.Thread.State: RUNNABLE

“附加侦听器”守护进程 prio=10 tid=0x02b52c00 nid=0x2450 等待条件 [0x00000000] java.lang.Thread.State: RUNNABLE

“信号调度程序”守护进程 prio=10 tid=0x02b51800 nid=0x11d4 可运行 [0x00000000] java.lang.Thread.State: RUNNABLE

“终结器”守护进程 prio=8 tid=0x02b4c000 nid=0x13bc in Object.wait() [0x02cdf000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - 等待在 <0x22991148> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118) - 锁定 <0x22991148> (a java.lang.ref.ReferenceQueue$Lock)在 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134) 在 java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

“引用处理程序”守护进程 prio=10 tid=0x02b47400 nid=0x2634 in Object.wait() [0x02c8f000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) -在 java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116) 的 java.lang.Object.wait(Object.java:485) 等待 <0x22991048> (a java.lang.ref.Reference$Lock) ) - 锁定 <0x22991048> (一个 java.lang.ref.Reference$Lock)

"main" prio=6 tid=0x002a6c00 nid=0x1fd4 等待条件 [0x0090f000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - 停车等待 <0x229c10d8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync) 在 java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196) 在 java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireNanos(AbstractQueuedSynchronizer.java: 905) 在 java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireNanos(AbstractQueuedSynchronizer.java:1224) 在 java.util.concurrent.locks.ReentrantLock.tryLock(ReentrantLock.java:416) 在 TestLock2.testOne(TestLock2.java:58) ) 在 TestLock2.test(TestLock2.java:44) 在 TestLock2.main(TestLock2.java:10)

“VM 线程”prio=10 tid=0x02b0a800 nid=0x11d0 可运行

“VM 周期性任务线程”prio=10 tid=0x02b65400 nid=0x1efc 等待条件

JNI 全局引用:975

有任何想法吗?

0 投票
0 回答
727 浏览

java - 寻找 ReentrantLock 的类似 priorityqueue 的替代方案,用于从其他线程窃取锁

我有一组ReentrantLocks具有唯一整数 id 的包装,我要求线程在获取更高 id 锁之前获取更低 id 锁,以防止死锁。其中三个锁(lock0、lock1 和 lock2)的优先级高于 id 较高的锁,而所有其他锁具有相同的优先级 - 这意味着如果一个线程获取这三个高优先级锁之一,那么它们需要中断持有必要低优先级锁的其他线程。例如,Thread1 持有 lock4 和 lock5,而 Thread0 持有 lock0 并需要 lock4 和 lock5,所以 Thread0 中断 Thread1(它使用它获取锁lockInterruptibly并且偶尔会查询它的锁)isInterrupted方法)并获取它的锁。Thread1 一直等待,直到 Thread0 发出信号(即它不会尝试重新获取锁,直到 Thread0 完成它们)。

由于几个原因,这并不理想。理想情况下,我希望 Thread0 立即发出信号,表示它需要锁,这样其他线程就不会向前跳转并在 Thread1 处理中断 Thread0 时获取锁(即 Thread0 进入等待线程的队列,这样如果 Thread2 尝试在 Thread0 中断 Thread1 时获取锁,然后 Thread0 仍将在 Thread2 之前获得锁) - 例如,我想要一个tryLock如果另一个线程持有锁,则将线程添加到锁的队列中。此外,目前如果有线程在 lock4 或 lock5 上排队,那么 Thread0 必须等待它们获取锁然后中断它们 - 如果 Thread0 可以清空锁上的等待队列会更好(假设没有等待线程持有高优先级锁)。最后,Thread1 没有必要放弃它所有的锁:如果 Thread0 想要 lock0 和 lock5 而 Thread1 想要 lock4 和 lock5,那么 Thread1 不需要放弃它对 lock4 的锁,但lockInterruptibly会导致线程中断时放弃所有锁(假设线程在等待获取锁时被中断)。

在我重新发明轮子之前,我想知道是否有一个锁类已经实现了一些/所有这些要求,某种PriorityReentrantLock或其他。我已经看过了AbstractQueuedSynchronizer,我认为修改它以满足我的需要不需要太多的工作(特别是因为我只需要两个优先级),但是我需要测试的新代码更少更好的。

0 投票
1 回答
290 浏览

java - Android 游戏循环中的高级并发

我正在尝试同步一对非 UI 线程,一个线程运行游戏逻辑,一个线程渲染,以便以逻辑和有效的顺序执行任务。我自己强加的一个约束是整个系统在无分配的稳定状态下运行,因此所有显示对象都被返回并“回收”,因此两个线程必须保持一种双向对话,当我调用'swapBuffers()' 方法。

在伪代码中,游戏线程中的事件顺序如下所示:

选择渲染线程来执行交换缓冲区的任务,以便游戏逻辑线程可以同时执行不修改缓冲区的任务。在我的代码中,我结合了交换缓冲区和渲染的任务,并将其定义为一个 Runnable 对象,该对象发布到渲染线程的处理程序。在伪代码中,该可运行文件如下所示:

我的问题是实施问题。我熟悉处理程序、同步块和 ReentrantLocks 的概念。我知道 Lock.await() Lock.signal() 方法,但是当我试图了解它们在迭代循环中调用时的行为时,我发现文档不足。

如何实现 ReentrantLocks 以使两个线程以这种方式相互等待?如果可能,请在您的答案中包含一个实用的成语。