我正在学习线程、锁等。因此,我不想使用synchronized
关键字或任何thread-safe
其他类semaphore
和ReentrantLock
(没有原子变量)。
我想要一种同步LinkedList<T>
的Node<T>
,按大小排序T
(假设它T
是implements
一个interface
具有size
和increment
功能和lock
,unlock
功能)。我希望能够Nodes
用它们的T.getSize()
功能替换两个而不锁定所有列表。
例如,如果我只有一个线程,该函数将是一个“经典”替换函数,如下所示:
public void IncrementAndcheckReplace(Node<T> node)
{
node.getData().incrementSize();
Node nextNode = node.getNext();
if(nextNode == null)
return;
while(node.getData().getSize() > nextNode.getData().getSize())
{
node.getPrev().setNext(nextNode);
nextNode.setPrev(node.getPrev());
Node nextnext = nextNode.getNext();
nextNode.setNext(node);
node.setPrev(nextNode);
node.setNext(nextnext);
nextnext.setPrev(node);
nextNode = node.getNext();
if(nextNode == null)
break;
}
}
现在让我们来解决同步问题。
我想过尝试做类似的事情来lock
为我创建一个Nodes
:
public void IncrementAndcheckReplace(Node<T> node)
{
node.lock(); //using fair ReentrantLock for specific node
node.getData().incrementSize();
Node nextNode = node.getNext();
if(nextNode == null)
{
node.unlock();
return;
}
nextNode.lock();
while(node.getData().getSize() > nextNode.getData().getSize())
{
Node prev = node.getPrev();
if(prev != null)
{
prev.lock();
prev.setNext(nextNode);
}
nextNode.setPrev(prev);
Node nextnext = nextNode.getNext();
if(nextnext != null)
{
nextnext.lock();
nextnext.setPrev(node);
}
nextNode.setNext(node);
node.setPrev(nextNode);
node.setNext(nextnext);
if(prev!=null)
prev.unlock();
if(nextnext!=null)
nextnext.unlock();
nextNode.unlock();
nextNode = node.getNext();
if(nextNode == null)
break;
nextNode.lock();
}
node.unlock();
}
问题是这并不是线程安全的,并且可能会发生死锁。例如,假设我们现在有Node a, Node b
那个a.next == b and b.prev==a
,如果线程 A 试图在 a 上使用替换函数,而线程 B 试图在 b 上使用替换函数,它们都将被锁定,我将无处可去。
如何使替换功能thread safe
没有lock
整个列表?我想避免dead-lock
and starvation
。
谢谢!