首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java锁:通过列表进行手动锁定

Java锁:通过列表进行手动锁定
EN

Stack Overflow用户
提问于 2017-05-03 14:19:34
回答 1查看 3.3K关注 0票数 1

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

我写了以下代码,wich不起作用。两个线程在列表中运行后,节点在某个点之后取值41。这意味着第二个线程在第一个线程之前对它们进行了编辑。我在谷歌上搜索了很多,也看过类似的问题,但仍然找不出答案。我真的很感谢你的帮助,谢谢!

代码语言:javascript
复制
import java.util.concurrent.locks.ReentrantLock;

类主{

代码语言:javascript
复制
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扩展线程{

代码语言:javascript
复制
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扩展线程{

代码语言:javascript
复制
Node current;

SecondThread(Node start) {
    current = start;
}

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

}

类节点{

代码语言:javascript
复制
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:我知道,如果线程被中断,我应该插入、尝试并最终阻塞,但不知道在哪里,所以忽略了这个事件。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-03 15:24:39

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

Lock对象可以是某个线程拥有的(即.k.a.,锁定的),也可以是可用的(即.a.,解锁)。

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

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

这基本上就是锁的全部*

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

防止“第二个线程”超越“第一个线程”的唯一方法是当第二个线程试图拥有相同的锁对象时被阻塞。

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

*除了“记忆可见度”,但那是另一个主题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43762688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档