作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
嗨,我遇到一种情况,我必须只允许一个线程更新变量。
有一个触发器,它可能会调用多个线程来更新此变量,但是更新只能由到达关键部分的第一个线程发生一次。
理想情况下,流程应如下所示:
线程1;调用 Thread-2 和 Thread-3 来更新由锁或互斥锁保护的临界区中的变量
使用此防护的临界区仅允许一个线程进入,Thread-2 和 Thread-3 在外面等待。
一旦该变量被 Thread-1 更新;线程 2 和线程 3 继续执行其他工作,而不会对变量造成影响。
我提出了以下实现,但我无法让其他线程等待并跳过更新:
public class Main {
private static ReentrantLock lock = new ReentrantLock();
private int counter = 0;
public static void main(String[] args) {
Main m = new Main();
new Thread(m::doSomeOperation).start();
new Thread(m::doSomeOperation).start();
new Thread(m::doSomeOperation).start();
}
private void doSomeOperation() {
try {
System.out.println("Thread about to acquire lock: " + Thread.currentThread().getName());
if (lock.tryLock()) {
System.out.println("Lock held by " + Thread.currentThread().getName() + " " + lock.isHeldByCurrentThread());
counter++;
// Thread.sleep(3000);
System.out.println("Counter value: " + counter + " worked by thread " + Thread.currentThread().getName());
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
System.out.println("Unlocked: " + Thread.currentThread().getName());
}
}
}
}
最后,计数器值为 3,我希望计数器值为 1,并且我希望其他线程等待,直到第一个线程更新计数器。想法表示赞赏。我更喜欢使用锁/互斥体的解决方案,而不是等待和通知。
输出:
Thread about to acquire lock: Thread-0
Lock held by Thread-0 true
Thread about to acquire lock: Thread-1
Counter value: 1 worked by thread Thread-0
Unlocked: Thread-0
Thread about to acquire lock: Thread-2
Lock held by Thread-2 true
Counter value: 2 worked by thread Thread-2
Unlocked: Thread-2
Process finished with exit code 0
注意我的用例是不同的 - 更新计数器的示例是为了简单起见。实际上我正在 doSomeOperation 方法中更新 session token 。
最佳答案
您可以在这里使用 AtomicInteger
并放弃担心形式锁:
public class Worker {
private static AtomicInteger counter = new AtomicInteger(0);
private void doSomeOperation() {
counter.incrementAndGet();
System.out.println("Counter value: " + counter + " worked by thread " + Thread.currentThread().getName());
}
}
public class Main {
public static void main(String[] args) {
Worker w = new Worker();
new Thread(w::doSomeOperation).start();
new Thread(w::doSomeOperation).start();
new Thread(w::doSomeOperation).start();
}
}
关于Java-允许一个线程更新值,其他线程等待并跳过关键部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58164463/
我是一名优秀的程序员,十分优秀!