Java-允许一个线程更新值,其他线程等待并跳过关键部分

标签 java multithreading locking mutex semaphore

嗨,我遇到一种情况,我必须只允许一个线程更新变量。

有一个触发器,它可能会调用多个线程来更新此变量,但是更新只能由到达关键部分的第一个线程发生一次。

理想情况下,流程应如下所示:

线程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/

相关文章:

iphone - 在iPad编程中使用多线程时出现问题(用于加载大量图像)

Java IO vs NIO vs 任务队列

python - python 中的锁创建

java - jdb 在给定的行或方法处停止

java - 如果 html 表格中任何单元格为空,如何突出显示整行

multithreading - TMultiReadExclusiveWriteSynchronizer死锁

mysql - 锁定 MySQL 中的特定记录

postgresql - 带有 postgres 插入/复制锁定和阻塞的并行聚合

java - 如何在Websphere应用程序服务器中安装端点URL的SSL证书

java - 如果需要更低延迟的代码,我们为什么要选择微服务?