简体   繁体   English

java强制获取锁?

[英]java forcing acquire of lock?

I am working with a somewhat outdated workflow engine, it allows for defining an individual step that executes Java code, but not more than this.我正在使用一个有点过时的工作流引擎,它允许定义执行 Java 代码的单个步骤,但仅此而已。

Each invocation of a workflow process operates in its own thread, with any subprocesses executing in the same thread synchronously.工作流进程的每次调用都在其自己的线程中运行,所有子进程在同一线程中同步执行。

The workflow engine does not allow for capturing of all exceptions that occur in a process.工作流引擎不允许捕获流程中发生的所有异常。 I need to make some subprocesses operate single-threaded, ie to wait if another thread is executing the subprocess.我需要让一些子进程运行单线程,即等待另一个线程是否正在执行子进程。

All I could come up with so far is to acquire a lock at the first step in a subprocess, and release it at the end steps.到目前为止我能想到的就是在子进程的第一步获取锁,并在最后的步骤释放它。 If an exception occurs in the process, it isn't always possible to capture it.如果过程中发生异常,并不总是可以捕获它。

... s_lock = new ReentrantLock(); ...
... s_timeout = 10; ...

public static void acquireLock() throws InterruptedException {
    if( !s_lock.tryLock(s_timeout, TimeUnit.SECONDS)) {
        System.out.println("WARN: Forcing acquire of lock.");
        s_lock = new ReentrantLock();   // discard old lock and create a new one
        s_lock.lock();
    }
}

public static void releaseLock() {
    if( s_lock.isHeldByCurrentThread()) {
        s_lock.unlock();
    } else {
        System.out.println("WARN:  lock not held by thread.");          
    }
}

There must be a better way?一定会有更好的办法? Is it possible to automatically release the lock if a thread terminates?如果线程终止,是否可以自动释放锁?

Is it possible to automatically release the lock if a thread terminates?如果线程终止,是否可以自动释放锁?

Not with any of the standard Lock implementations.不适用于任何标准Lock实现。 AFAIK, they all have the restriction that only the thread that acquired a lock can release it. AFAIK,它们都有限制,只有获得锁的线程才能释放它。 So in your use-case where each workflow process is in a different thread, a later workflow process cannot cannot break a lock abandoned when an earlier process fails.因此,在您的用例中,每个工作流进程都在不同的线程中,后面的工作流进程不能打破在前面的进程失败时放弃的锁。

But all is not lost.但一切都没有丢失。 The javadoc for Lock.unlock() says this: Lock.unlock()的 javadoc 说:

Implementation Considerations实施注意事项

A Lock implementation will usually impose restrictions on which thread can release a lock (typically only the holder of the lock can release it) and may throw an (unchecked) exception if the restriction is violated. Lock 实现通常会对哪个线程可以释放锁施加限制(通常只有锁的持有者可以释放它)并且如果违反限制可能会抛出(未经检查的)异常。 Any restrictions and the exception type must be documented by that Lock implementation.该 Lock 实现必须记录任何限制和异常类型。

Note that the restriction is not mandated.请注意,该限制不是强制性的。 So you could write your own Lock implementation without the restriction on unlock() .因此,您可以编写自己的 Lock 实现,而不受unlock()的限制。

Furthermore, if you can guarantee that the threads that run workflow processes are not reused, there is a scheme that could be used to break the lock safely .此外,如果您可以保证运行工作流进程的线程不被重用,则可以使用一种方案来安全地打破锁定。

  • When a thread acquires one of these locks, it passes a tuple consisting of the current Thread object and the lock to a separate lock monitor thread.当一个线程获得这些锁之一时,它会将一个由当前Thread对象和锁组成的元组传递给一个单独的锁监视器线程。

  • The lock monitor thread periodically scans the tuples for all outstanding locks.锁监视器线程定期扫描元组中所有未完成的锁。

  • For each tuple, the monitor calls Thread.isAlive() to test if the thread holding the lock is still running.对于每个元组,监视器调用Thread.isAlive()来测试持有锁的线程是否仍在运行。 When a thread with a lock is no longer running, the monitor thread unlocks the lock, and discards the tuple.当带锁的线程不再运行时,监视器线程解锁锁,并丢弃元组。

This unfortunately entails polling, but you should be able to implement this so that the monitor thread only polls while there are locks in acquired state.不幸的是,这需要轮询,但您应该能够实现这一点,以便监视器线程仅在获取状态的锁存在时进行轮询。


Implementing the custom Lock class and the lock monitor would not be trivial ...实现自定义Lock类和锁监视器并非易事......


By the way, your current approach is flawed:顺便说一句,您目前的方法有缺陷:

  • If the timeout is small, there is a risk that you will break the lock while the original workflow process is still running.如果超时时间很短,则存在在原始工作流进程仍在运行时打破锁定的风险。

  • If the timeout is large, then a failed workflow process may block other workflow processes for too long.如果超时很大,则失败的工作流进程可能会阻塞其他工作流进程太长时间。

  • There is no "half-way" point where you get guaranteed reliable locks and responsiveness.没有“中途”点可以保证可靠的锁定和响应能力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM