是否可以在一种方法中获取锁并从另一种方法中释放它?
我基本上使用的是一个框架,它从两个不同的线程调用一堆函数。我希望在允许下一个线程继续之前完成整个线程。但是,我无法更改那里的代码。
例如,假设有两个线程:线程 1 和线程 2。每个线程调用方法一到方法三。
所以你会得到一个类似于以下的调用顺序:
T1-M1 T1-M2 T2-M1 T1-M3 T2-M2 T2-M3
但是,我希望发生的是 T1-M1 设置某种会阻止 T2 的锁,因此顺序如下。
T1-M1 - get lock T2-M1 - blocked T1-M2 T1-M3 - release lock T2-M1 - no longer blocked - gets lock T2-M2 T2-M3
是否可以在 Java 中执行此操作,而无需编辑框架中的调用方法?
I basically I am using a frame work that calls a bunch of functions from two different threads. I would like one entire thread to complete before the next thread is allow to continue. However, I can not change there code.
For example suppose there are two threads, thread 1 and thread 2. Each thread calls methods one through three.
So you get a call order something like:
T1-M1 T1-M2 T2-M1 T1-M3 T2-M2 T2-M3
However, what I would like to have happen is T1-M1 one sets some sort of lock that will block T2, so the order will be as follows.
T1-M1 - get lock T2-M1 - blocked T1-M2 T1-M3 - release lock T2-M1 - no longer blocked - gets lock T2-M2 T2-M3
Is it possible to do this in Java without editing the calling method from the framework?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您无法使用
synchronized
关键字提供的简单功能来做到这一点:它的锁必须在获取它的同一方法(偶数块)中释放。您可以使用 < 中的工具但是,代码>java.util.concurrent.locks。
它是
ReentrantLock
类几乎是具体化同步
机制。但请记住,这种方法是危险的。如果线程调用
M1
和M2
,但从不调用M3
,该怎么办?例如,在调用M2
和M3
之间的某些代码中可能会出现异常。You can't do that with the simple features provided by the
synchronized
keyword: its lock must be released in the same method (even block) on which it's acquired.You can use the tools in
java.util.concurrent.locks
, however.It's
ReentrantLock
class is pretty much a reification of thesynchronized
mechanism.Bear in mind that such an approach is dangerous, however. What if a thread calls
M1
andM2
, but never callsM3
? It might get an exception in some code between the calls toM2
andM3
, for example.您无法从另一个方法释放内在锁,但可以从另一个方法释放 jucLock。例如:(根据 Peter Lawrey 的回复进行编辑,谢谢)
这里提供了一种在超时时中断地获取锁的便捷方法。
现在让我们来看看陷阱。如果您使用不同的方法锁定和解锁,则必须小心在此过程中可能发生的任何异常。不考虑这一点可能会导致死锁问题。
现在,如果
otherMethodWork()
抛出RuntimeException
该怎么办?您的代码现在将永远无法调用releaseLock()
并且无法取得更多进展。这就是为什么指示使用样式
如果 //work 中发生任何错误,您仍然可以解锁并取得进展。
You cannot release an intrinsic lock from another method but you can release a j.u.c.Lock from another method. For example: (Edited based on Peter Lawrey's response, thanks)
Here offers a convenience method to acquire a lock interruptbly with a timeout.
Now lets get to the pitfalls. If you lock and unlock from different method you have to be careful of any exception that can occur during the process. Failure to account for this can lead to a deadlock issue.
Now what if
otherMethodWork()
throws aRuntimeException
? Your code will now never be able to invokereleaseLock()
and no more progress can be made.This is why it is instructed to use the style
If anything wrong happens in //work you will still be able to unlock and make progress.
如果您不想控制来自框架层的调用,您可以通过将此逻辑设置到每个线程中来验证它们何时可以访问每个方法,您可以使用会话变量作为标志,例如控制方法何时可用于任何其他线程,因此您只需调用线程,它们将具有访问方法的验证。-
If you do not want to control the calling from the framework layer you can do it by setting this logic into every thread you have validating when they can access to every single method, you can use session variables as flags for example to control when the method is available to any other so you can just call the threads and they will have the validations to access the methods.-
只是对其他帖子的补充,所有 3 个方法必须共享相同的锁,这里的共享资源是 3 个方法的捆绑,当 T2 已经锁定时,您不希望 T1 获得 M1 和 M2 的锁定M3。
Just a complement of the other posts, all 3 methods have to share the same lock, the shared resource here is the bundle of the 3 methods, you don't want T1 getting a lock on M1 and M2 when T2 has already a lock on M3.