我试图理解java.util.concurrent.locks库,并希望实现两个线程,它们通过一个列表运行,而第二个线程不应该超过(带头)第一个线程。具体来说,我想实现手对手的锁定。
我写了以下代码,wich不起作用。两个线程在列表中运行后,节点在某个点之后取值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:我知道,如果线程被中断,我应该插入、尝试并最终阻塞,但不知道在哪里,所以忽略了这个事件。
发布于 2017-05-03 15:24:39
看起来你可能不明白Lock是什么。
Lock对象可以是某个线程拥有的(即.k.a.,锁定的),也可以是可用的(即.a.,解锁)。
当锁l不属于任何线程时,对l.lock()的调用将更改为由调用线程拥有,然后立即返回;但是如果l为其他线程所拥有,则l.lock()线程将等待(即.a.,它将阻塞),直到另一个线程通过调用l.unlock()释放其所有权。
锁永远不能由多个线程拥有,而l.lock()将在调用线程成为所有者之前不会返回。
这基本上就是锁的全部*
您的“第一个线程”获取并释放列表中的锁的所有权,但是您的“第二个线程”完全忽略锁。
防止“第二个线程”超越“第一个线程”的唯一方法是当第二个线程试图拥有相同的锁对象时被阻塞。
此外,您还需要一些机制来防止“第二个线程”在“第一个线程”运行之前启动列表。不能保证线程按照与start()线程相同的顺序运行。
*除了“记忆可见度”,但那是另一个主题。
https://stackoverflow.com/questions/43762688
复制相似问题