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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16491287/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:06:52  来源:igfitidea点击:

Unlocking lock owned by another thread java

javalocksreentrantlock

提问by Flame_Phoenix

I have a LockManager that manages the locks of several threads. Sometimes the threads are bad boys, and I have to kill them and ask the LockManager to release all their locks. However, since I use ReentrantLock in java this is impossible, I can not unlock a lock owned by another thread.

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

I am forced to use Locks (cannot use semaphores, it is point of the homework). Is there any Java Lock implementation that allows me to unlock locks owned by other threads?

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

So far the options I considered are:

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

  • re-implementing ReentrantLock in a way that allows me to do this
  • Make some sort of mapping between Semaphores and ReentrantLocks
  • 以允许我这样做的方式重新实现 ReentrantLock
  • 在 Semaphore 和 ReentrantLocks 之间进行某种映射

Extra Sources you may find useful:

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

采纳答案by OldCurmudgeon

Would you be allowed to use your own Lock? Here's a class that completely proxies the Lockbut when it is told to force the unlock it merely replaces the lock it is proxying with a new one. This should have the effect you want. Sadly it still does not deal with the locks that are left dangling but that now becomes somebody else's problem. Your locks are now magically unlocked.

你会被允许使用你自己的Lock吗?这是一个完全代理的类,Lock但是当它被告知强制解锁时,它只是用新的锁替换了它代理的锁。这应该有你想要的效果。可悲的是,它仍然没有处理悬空的锁,但这现在变成了其他人的问题。你的锁现在神奇地解锁了。

static class LockProxy<L extends Lock> implements Lock {

    // The actual lock.
    private volatile Lock lock;

    public LockProxy(L lock) {
        // Trap the lock we are proxying.
        this.lock = lock;
    }

    @Override
    public void lock() {
        // Proxy it.
        lock.lock();
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        // Proxy it.
        lock.lockInterruptibly();
    }

    @Override
    public boolean tryLock() {
        // Proxy it.
        return lock.tryLock();
    }

    @Override
    public boolean tryLock(long l, TimeUnit tu) throws InterruptedException {
        // Proxy it.
        return lock.tryLock(l, tu);
    }

    @Override
    public void unlock() {
        // Proxy it.
        lock.unlock();
    }

    @Override
    public Condition newCondition() {
        // Proxy it.
        return lock.newCondition();
    }

    // Extra functionality to unlock from any thread.
    public void forceUnlock() {
        // Actually just replace the perhaps locked lock with a new one.
        // Kinda like a clone. I expect a neater way is around somewhere.
        if (lock instanceof ReentrantLock) {
            lock = new ReentrantLock();
        } else {
            throw new UnsupportedOperationException(
                "Cannot force unlock of lock type "
                    + lock.getClass().getSimpleName());
        }
    }
}

回答by Dale Wilson

You've discovered a major reason why common wisdom says: Don't kill threads!

您已经发现了常识说的一个主要原因:不要杀死线程!

Locks are only one of the potential resource leaks that can happen if you forcibly kill a thread. Consider open files and sockets, etc.

如果您强行杀死​​线程,锁定只是可能发生的潜在资源泄漏之一。考虑打开的文件和套接字等。

Also consider that if you did manage to unlock the lock, there was a reason the lock was locked in the first place. For example, the thread may have partially updated a data structure, and allowing access to that structure from another thread is likely to cause strange and wondrous program failures that are difficult if not impossible to debug.

还要考虑一下,如果您确实设法解锁了锁,那么锁首先被锁定是有原因的。例如,线程可能已经部分更新了一个数据结构,并且允许从另一个线程访问该结构很可能导致奇怪而奇妙的程序故障,这些故障即使不是不可能也很难调试。

The best way to handle this situation is to ask the thread to go away. Add a "stop()" method to the object associated with the thread (you do have an object for each thread, don't you?) that sets a flag, and have the thread check this flag regularly and exit if it is set.

处理这种情况的最好方法是要求线程离开。向与线程关联的对象添加一个“stop()”方法(每个线程都有一个对象,不是吗?)设置一个标志,并让线程定期检查这个标志,如果设置了就退出.

If your threads are misbehaving in a way that prevents them from checking the stop flag, then the correct approach is to fix the code so that it does not misbehave.

如果您的线程以某种方式行为不当而无法检查停止标志,那么正确的方法是修复代码,使其不会行为不当。

回答by Kurt

I've done this with an AtomicReference which gets zero points for elegance, but I don't know of another way.

我已经用 AtomicReference 做到了这一点,它在优雅方面得到了零分,但我不知道另一种方式。

class PseudoLock {

    private final AtomicReference<Boolean> mylock = new AtomicReference<>(Boolean.FALSE);


    boolean trylock() {
        return mylock.compareAndSet(Boolean.FALSE, Boolean.TRUE);
    }

    void unlock() {
        boolean done = mylock.compareAndSet(Boolean.TRUE, Boolean.FALSE);
        if (!done) {
            throw new IllegalStateException("Cannot unlock an unlocked thread");
        }
    }
}

''''

''''

回答by benez

As stated in the comments, killing threads is not a good practice. Most frameworks do their best to interrupt threads in worker queues, but they will only have an effect if the executed code checks the interrupt flag, either by calling Thread.isInterrupted()or calling an interruptable IO or lock method.

正如评论中所述,杀死线程不是一个好习惯。大多数框架都尽力中断工作队列中的线程,但只有在执行的代码通过调用Thread.isInterrupted()或调用可中断 IO 或锁定方法检查中断标志时,它们才会起作用。

If you really need the concept of killing the execution of code, have a look at the Processclass. You can create a Processby calling Runtime.exec()or using the ProcessBuilder. Calling Process.destroyForcibly()will forcibly terminate the running process.

如果您真的需要杀死代码执行的概念,请查看Process该类。您可以Process通过调用Runtime.exec()或使用ProcessBuilder. 调用Process.destroyForcibly()会强制终止正在运行的进程。

回答by Bruno Reis

Why don't you simply wrap the code of your thread around the following:

为什么不简单地将线程代码围绕以下内容包装起来:

ReentrantLock lock = ... obtain your lock somehow ...
lock.lock();
try {
  ... the "bad boy" code here ...
} finally {
  lock.unlock();
}

Then, when your thread finishes (either by normally finishing, or by throwing an exception from your "kill"), it will release the lock.

然后,当您的线程完成时(通过正常完成,或通过“kill”抛出异常),它将释放锁。

This is actually the way Oracle recommends using ReentrantLock: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html

这实际上是 Oracle 推荐使用 ReentrantLock 的方式:http: //docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html