如果一个线程已经获取了锁,我希望其他线程跳过获取锁的尝试,只需等待释放锁,然后再继续执行。我不希望其他线程在释放锁后获取它。
我一直在研究这个问题,但仍然感到困惑。
请参阅以下通用代码段:
private final ReentrantLock reentrantLock = new ReentrantLock();
public void aCoolMethod(){
if (reentrantLock.tryLock() == true){
try {
doSomething();
} finally {
reentrantLock.unlock();
}
} else {
// have threads wait until reentrantLock is unlocked
}
doSomethingElse();
}
我怎么能让线程进入我的其他块等待重入锁被解锁之前继续执行?
发布我最终使用的解决方案,以防其他人有类似问题。我选择使用等待通知策略。虽然其他答案很有帮助,但这对我的情况很有效,而且足够简单。
private final ReentrantLock reentrantLock = new ReentrantLock();
public void aCoolMethod(){
if (reentrantLock.tryLock()){
try {
doSomething();
} finally {
reentrantLock.unlock();
synchronized (reentrantLock) {
reentrantLock.notifyAll();
}
}
} else {
// have threads wait until reentrantLock is unlocked
synchronized (reentrantLock) {
while(reentrantLock.isLocked()) {
try {
reentrantLock.wait();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
}
}
doSomethingElse();
}
编辑:发布测试类,以便其他人可以测试此解决方案。只需复制/粘贴并运行它。见下文:
import java.util.concurrent.locks.ReentrantLock;
import java.lang.Thread;
public class LockTest {
public static void main(String args[]){
TestClass testClass = new TestClass();
Thread thread0 = new Thread () {
public void run () {
testClass.testLock();
}
};
Thread thread1 = new Thread () {
public void run () {
testClass.testLock();
}
};
Thread thread2 = new Thread () {
public void run () {
testClass.testLock();
}
};
thread0.start();
thread1.start();
thread2.start();
}
public static class TestClass{
ReentrantLock reentrantLock = new ReentrantLock();
public void testLock(){
if (reentrantLock.tryLock()) {
try {
System.out.println("Locking");
System.out.println(Thread.currentThread().getName() + " will sleep");
Thread.sleep(8000);
System.out.println(Thread.currentThread().getName() + " has woken up from sleep!!");
} catch (InterruptedException i) {
System.out.println("Interrupted during sleep");
} finally {
System.out.println("Unlocking");
reentrantLock.unlock();
System.out.println("Notifying");
synchronized (reentrantLock) {
reentrantLock.notifyAll();
}
}
} else {
synchronized (reentrantLock) {
while(reentrantLock.isLocked()) {
try {
System.out.println(Thread.currentThread().getName() + " will wait");
reentrantLock.wait();
System.out.println(Thread.currentThread().getName() + " has woken up from wait!!");
} catch (InterruptedException i) {
System.out.println("Interrupted during wait");
}
}
}
}
System.out.println(Thread.currentThread().getName() + " has reached the end.");
}
}
}
正如Thilo所提到的,解决问题的更好方法是有一个关键部分,其中包含线程首先检查的标志。如果尚未设置标志,请解决问题并在退出关键部分之前设置标志。如果已经设置了标志,那么您知道另一个线程首先到达了那里并解决了问题,所以只需退出关键部分。
private final ReentrantLock reentrantLock = new ReentrantLock();
private boolean fixed = false;
public void aCoolMethod(){
try {
reentrantLock.lock();
if (!fixed) {
doSomething();
}
} finally {
fixed = true;
reentrantLock.unlock();
}
doSomethingElse();
}
或者,在没有锁的情况下,您可以使用一致对象来确定哪个线程运行
private final AtomicBoolean turn = new AtomicBoolean(true);
private volatile boolean done = false;
public void aCoolMethod(){
if (turn.compareAndSet(true, false)) {
doSomething();
done = true;
} else {
while (!done) {
// spin or wait for condition
}
doSomethingElse();
}
}
我打算在主线程中启动2个线程,主线程应该等到所有2个子线程完成,我就是这样做的。 在上面的代码中,确实让主线程等待子线程,但问题是,在第一个线程完成之前不会创建第二个线程。这不是我想要的。 我想要的是,这两个线程立即在主线程中创建,然后主线程等待它们完成。似乎做不到,是吗? 我想,也许我可以通过一个信号灯来完成这项工作,但还有别的方法吗?
我是一个初学者,我正在实施餐饮哲学家的问题。然而,我遇到了一个问题。在我的哲学家()函数中,我希望我的其他线程等待,直到左右筷子都可以使用。我应该如何实现这一点?目前,该计划只是在两位哲学家吃完后终止,而不等待其他人吃完 我已经试过了: 使用互斥锁来锁定哲学家()函数中的共享变量,虽然可以确保没有哲学家挨饿,但使用这种方法意味着放弃并发(即使有筷子可供其他哲学家使用,一次也只能有一位哲学家吃饭)
有时我看到一些线程还没有完成他们的工作,服务杀死那个线程,我怎么能强迫服务等待,直到线程完成他们的工作? 这是我的代码: 我看到了一些例外。future.is完成())块。我怎么能确保每一个未来是当执行者服务关闭?
问题内容: 在这里,我想每秒钟调用一次“ Log.d”和“ postInvalidate”。但是,当我从LogCat检查它时,似乎循环运行的速度比我希望的要快。为什么这个循环不等待1000ms? 以下是LogCat中的输出。因此,您可以看到它根本没有休眠1秒钟。我也使用了Thread.sleep(在您建议之后) 这是最新的代码。是布尔值,现在是事实。 输出是 问题答案: 您需要类的方法。 使发送此
问题内容: 我正在为我的ubuntu服务器(针对我的多客户端匿名聊天程序)实现一种简单的线程池机制,并且需要使我的工作线程进入睡眠状态,直到需要执行一项工作(以函数指针和参数的形式) 。 我当前的系统即将关闭。我(工人线程正在)问经理是否有工作可用,以及是否有5毫秒没有睡眠。如果存在,请将作业添加到工作队列中并运行该函数。糟糕的循环浪费。 什么我 喜欢 做的是做一个简单的事件性的系统。我正在考虑有
问题内容: 我找不到如何测量线程等待锁定的时间。我必须确定一个线程是否正在等待锁定超过1秒,如果需要,则运行另一个线程。谢谢! 问题答案: 试试这个: