Java锁:通过列表

时间:2017-05-03 14:19:35

标签: java multithreading concurrency locking reentrantlock

我正在尝试理解java.util.concurrent.locks库并想要实现两个运行列表的线程,而第二个线程不应该超越(带头)第一个线程。具体来说,我想实现手动锁定。

我写了下面的代码,但是没有用。在两个线程遍历列表之后,节点在某个点之后取值41。这意味着第二个线程在第一个线程编辑之前编辑了它们。我google了很多,也看了类似的问题,但仍然无法弄明白。非常感谢你的帮助,谢谢!!

import java.util.concurrent.locks.ReentrantLock;

class Main {

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();
}

}

class FirstThread扩展了Thread {

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();
}

}

类Sec​​ondThread扩展了线程{

Node current;

SecondThread(Node start) {
    current = start;
}

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

}

class Node {

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块,如果线程被中断但不知道在哪里,那么只是忽略了那个事件。

1 个答案:

答案 0 :(得分:0)

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

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

当锁l不属于任何线程时,对l.lock()的调用会将其更改为由调用线程拥有,然后它将立即返回;但如果l由其他某个线程拥有,那么l.lock()线程将等待(也就是说,阻塞),直到另一个线程通过调用{{1}释放其所有权}}

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

基本上只有锁定。*

你的&#34;第一个帖子&#34;获取并释放列表中锁的所有权,但是您的第二个线程&#34;完全忽略了锁。

唯一会阻止&#34;第二个线程&#34;从超越&#34;第一线程&#34;如果第二个线程在尝试拥有相同的锁定对象时被阻止。

另外,你需要一些机制来阻止&#34;第二个线程&#34;从开始之前第一个线程&#34;运行。不保证线程的运行顺序与l.lock()它们相同。

*除了&#34;内存可见性&#34;,但这是另一个主题。