Java锁: Hand over hand locking through list

标签 java multithreading concurrency locking reentrantlock

我试图理解 java.util.concurrent.locks 库,并希望实现两个通过列表运行的线程,而第二个线程不应超过(领先)第一个线程。具体来说,我想实现手动锁定。

我写了下面的代码,但不起作用。两个线程运行完列表后,节点在某个点之后取值 41。这意味着第二个线程在第一个线程之前编辑它们。我用谷歌搜索了很多,也看了类似的问题,但仍然无法弄清楚。我非常感谢您的帮助,谢谢!!

import java.util.concurrent.locks.ReentrantLock;

主类{

public static void main(String[] args) throws InterruptedException {
    // Generate List
    Node first = new Node();
    Node current = first;
    for(int i = 0; i < 50; i++) {
        current.next = new Node();
        current = current.next;
    }

    // run Threads
    FirstThread a = new FirstThread(first);
    SecondThread b = new SecondThread(first);
    a.start();
    b.start();
    a.join();
    b.join();

    // Print result
    first.print();
}

}

类 FirstThread 扩展了线程 {

Node current;

FirstThread(Node start) {
    this.current = start;
}

public void run() {
    // =================> HAND OVER HAND LOCKING <=================
    current.lock.lock();
    while(current.next != null) {
        current.value = 41;
        current.next.lock.lock();
        current.lock.unlock();
        current = current.next;
    }
    current.value = 41;
    current.lock.unlock();
}

}

类 SecondThread 扩展了线程 {

Node current;

SecondThread(Node start) {
    current = start;
}

public void run() {
    while(current != null) {
        current.value++;
        current = current.next;
    }
}

}

类节点{

ReentrantLock lock;
Node next;
int value;

Node() {
    lock = new ReentrantLock();
    next = null;
    value = 0;
}

public void print() {
    Node current = this;
    while(current != null) {
        System.out.print(current.value + " ");
        current = current.next;
    }
    System.out.println();
}

}

PS:我知道如果线程被中断,我实际上应该插入 try 和finally block ,但不知道在哪里,所以忽略了该事件。

最佳答案

看起来您可能不明白Lock是什么。

Lock 对象可以由某个线程拥有(也称为锁定),也可以可用(又名,解锁)。

当锁 l 不属于任何线程时,调用 l.lock() 会将其更改为由调用线程拥有,然后将立即返回;但如果 l 由某个其他线程拥有,则 l.lock() 线程将等待(又名,它将阻塞),直到其他线程通过调用l.unlock()释放其所有权。

锁永远不会被多个线程拥有,并且 l.lock() 在调用线程成为所有者之前不会返回。

这基本上就是锁的全部内容。*

您的“第一个线程”获取并释放列表中锁的所有权,但您的“第二个线程”完全忽略这些锁。

唯一可以阻止“第二个线程”超越“第一个线程”的事情是,如果第二个线程在尝试拥有相同的锁对象时被阻塞。

此外,您还需要某种机制来防止“第二个线程”在“第一个线程”运行之前启动列表。不保证线程按照 start() 启动它们的顺序运行。

<小时/>

*除了“内存可见性”,但那是一个完全不同的主题。

关于Java锁: Hand over hand locking through list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43762688/

相关文章:

具有 Future 返回类型的 Scala 递归函数

java - 这是没有被破坏的双重检查锁定吗?

java - 从复杂数据结构中删除对象的所有实例

c++ - 对于 CPU 无法原子操作的类型,std::atomic 有什么意义?

java - Java 是否在不使用 try 和 catch block 的情况下自动处理异常?

java - 获取 InterruptedException 以忽略中断

Swift 控制流(函数调用)

c++ qthread同时启动2个线程

java - 将私有(private)构造函数用于工厂方法?

java - 必须扩展类 A 并实现一些接口(interface)的成员变量