gpt4 book ai didi

java - 条件变量和锁的使用

转载 作者:行者123 更新时间:2023-12-02 04:04:41 25 4
gpt4 key购买 nike

我目前正在尝试实现一个受线程保护的链表。要实现的方法之一是 take(),它删除最近添加的元素,并在列表为空时等待添加元素。我对 Java 线程和同步的了解很差,所以我想知道这个实现是否有效。特别是,我想知道如果在 put() 之前调用 take() 会发生什么。由于它们都使用相同的锁对象,我觉得如果在 put() 之前调用 take(),take() 的锁永远不会释放,因此 put() 将在尝试获取该 lock() 时被卡住。这是我的实现

//Globals
private final Lock lock = new ReentrantLock();
final Condition notEmpty = lock.newCondition();

public boolean put(int address) {
Node newnode = new Node(null, null, address);
lock.lock();
if(first == null) {
try {
first = newnode;
last = newnode;
size++;
notEmpty.signal();
}
finally {
lock.unlock();
}
}
else {
if(contains(address) == true) {
remove(address);
}

first.prev = newnode;
newnode.next = first;
first = newnode;
size++;
}

return true;
}

为了拍摄

    public int take() throws InterruptedException {
lock.lock();
try{
while(size() == 0)
notEmpty.await();
remove();
}
finally {
lock.unlock();
}
}

任何帮助都会很棒!谢谢。

最佳答案

我认为你应该考虑使用“java.util.Stack ”。

Java 堆栈已经同步,并且具有 pop() 和 push() 方法,您可以从 take() 和 put() 调用它们,而不必担心锁。

现在你需要做的就是在take()中等待如果堆栈对象为空,你可以为堆栈对象设置一个监听器,或者你启动一个类参数int takeCalled = 0并在每次使用空堆栈调用 take() 时增加它:

public void take(){
if (stackObj.isempty()) takeCalled++;
else stackObj.pop();
}

然后在 put() 中做一个简单的检查,如果 takeCalled > 0

则清空堆栈
public void put(x){
stackObj.push(x);
while(!stackObj.isEmpty()) take();
}

我总是更喜欢在实现中使用同步构建,因为您不能授予无错误逻辑。例如,如果 first != null,则 put 不会释放锁。

关于java - 条件变量和锁的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34475170/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com