-
Notifications
You must be signed in to change notification settings - Fork 0
Harris's List
Pslydhh edited this page Oct 5, 2017
·
1 revision
package org.psly.concurrent;
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class LockFreeLinkedList> {
public LockFreeLinkedList() {
super();
this.tail = new Node(null, null);
this.head = new Node(null, new NodePacket(this.tail, false));
}
public boolean insert(E e){
Node node = new Node(e, null);
Object[] nodes;
//查找该元素
for(;;){
nodes = search(e);
@SuppressWarnings("unchecked")
Node left = (Node) nodes[0];
@SuppressWarnings("unchecked")
NodePacket leftNext = (NodePacket) nodes[1];
if(leftNext.node != tail && (leftNext.node.value.compareTo(e) == 0))
return false;
node.next = new NodePacket(leftNext.node, false);
if(left.casNext(leftNext, node, leftNext.deleting))
return true;
}
}
@SuppressWarnings("unchecked")
public boolean delete(E e){
Object[] nodes;
Node left;
NodePacket leftNext;
Node right;
for(;;) {
nodes = search(e);
left = (Node) nodes[0];
leftNext = (NodePacket) nodes[1];
NodePacket rightNext;
if((right = leftNext.node) == tail || (right.value.compareTo(e) != 0))
return false;
if((!(rightNext = right.next).deleting)
&& right.casNext(rightNext, rightNext.node, true))
break;
}
if(!left.casNext(leftNext, right.next.node, leftNext.deleting))
search(e);
return true;
}
private Object[] search(E key){
searchAgain:
for(;;){
Node prev = head;
NodePacket prevNext = head.next;
Node curNode = prevNext.node;
/* 1: Find left_node and right_node */
for(;;){
if(curNode == tail)
break;
if(curNode.next.deleting){
curNode = curNode.next.node;
continue;
}
if(key.compareTo(curNode.value) <= 0){
break;
} else {
prev = curNode;
prevNext = curNode.next;
curNode = prevNext.node;
}
}
Node rightNode = curNode;
//相邻的两个
if(prevNext.node == rightNode){
if((rightNode != tail) && rightNode.next.deleting)
continue searchAgain;
else
return new Object[]{prev, prevNext};
}
//不相邻,将中间的这些通通删除
if(prev.casNext(prevNext, prevNext = new NodePacket(rightNode, prevNext.deleting))){
if((rightNode != tail) && rightNode.next.deleting)
continue searchAgain;
else
return new Object[]{prev, prevNext};
}
}
}
public String toString(){
NodePacket nNext = head.next;
StringBuilder strBuild = new StringBuilder();
for(;;){
if(nNext.node == tail)
break;
//获取节点
Node node = nNext.node;
strBuild.append(node.value).append("\n");
nNext = node.next;
}
return strBuild.toString();
}
public int size(){
NodePacket nNext = head.next;
int num = 0;
for(;;){
if(nNext.node == tail)
break;
//获取节点
Node node = nNext.node;
++num;
nNext = node.next;
}
return num;
}
public final Node head;
public final Node tail;
public static class Node{
final E value;
volatile NodePacket next;
private static final sun.misc.Unsafe UNSAFE;
public Node(E value, NodePacket next) {
super();
this.value = value;
this.next = next;
}
private static final long nextOffset;
boolean casNext(NodePacket cmp, Node node, boolean deleting){
return casNext(cmp, new NodePacket(node, deleting));
}
boolean casNext(NodePacket cmp, NodePacket val){
return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
}
static{
try{
UNSAFE = UtilUnsafe.getUnsafe();
nextOffset = UNSAFE.objectFieldOffset(Node.class.getDeclaredField("next"));
} catch(Exception e){
throw new Error(e);
}
}
}
public static class NodePacket{
final Node node;
final boolean deleting;
public NodePacket(Node node, boolean deleting) {
super();
this.node = node;
this.deleting = deleting;
}
public Node getNode() {
return node;
}
public boolean isDeleting() {
return deleting;
}
}
private static class UtilUnsafe {
private UtilUnsafe() {
}
/** Fetch the Unsafe. Use With Caution. */
public static Unsafe getUnsafe() {
if (UtilUnsafe.class.getClassLoader() == null)
return Unsafe.getUnsafe();
try {
final Field fld = Unsafe.class.getDeclaredField("theUnsafe");
fld.setAccessible(true);
return (Unsafe) fld.get(UtilUnsafe.class);
} catch (Exception e) {
throw new RuntimeException("Could not obtain access to sun.misc.Unsafe", e);
}
}
}
}