自旋+CAS实现java同步锁,代码存在很多问题

GetUnsafe

import sun.misc.Unsafe;

import java.lang.reflect.Field;

public class GetUnsafe {
public static Unsafe getUnsafe(){
try {
Field field=Unsafe.class.getDeclaredField(“theUnsafe”);
field.setAccessible(true);
return (Unsafe)field.get(null);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

Lock

import sun.misc.Unsafe;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.LockSupport;

public class Lock {
//jdk提供的可以直接操作内存数据的类
private static final Unsafe unsafe = GetUnsafe.getUnsafe();

private  static  long stateOffset;
//记录0和1状态 0表示当前没有线程占用锁,1则反之
private  volatile int state=0;

//当前拿到锁的线程
private  volatile Thread thisThread=null;

private  static  long headOffset;
//拿到锁的节点头部
private volatile Node head=null;

private  static  long tailOffset;
//排队等候的节点尾部
private volatile Node tail=null;


static{
    try {
        stateOffset= unsafe.objectFieldOffset(Lock.class.getDeclaredField("state"));
        headOffset= unsafe.objectFieldOffset(Lock.class.getDeclaredField("head"));
        tailOffset= unsafe.objectFieldOffset(Lock.class.getDeclaredField("tail"));
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    }
}



private  boolean acquire(){
    if(state==0 && thisThread==null){
        if(compareAndSwapInt(stateOffset,0,1)){
            thisThread=Thread.currentThread();
            return true;
        }
    }
    return false;
}
/**
 * 获取锁
 * */
public void lock(){
    Thread thread = Thread.currentThread();
   if(acquire()){//拿到锁直接返回
       return;
   }
    //没有拿到锁添加的队列
    addNode();
    LockSupport.park(thread);
   for(;;){
       if(acquire()){
           break;
       }else {
        // System.out.println(thread.getName()+"线程没有拿到锁");
       }
   }
}

/**
 * 释放锁
 * */
public void unlock(){
    Thread thread = Thread.currentThread();
    if(thread!=thisThread){
        throw new RuntimeException(thread.getName()+"没有权限释放"+thisThread.getName()+"加的锁");
    }
    for(;;){
        thisThread=null;
        if(compareAndSwapInt(stateOffset,1,0)){
            Node node=getNode();
            if(node!=null){
                LockSupport.unpark(node.thread);
            }
            break;
        }else {
            System.out.println(thread.getName()+"没有释放的锁");
        }
    }
}




/**
 * 从尾部添加链表节点
 * */
public Node addNode(){
    for(;;){
        Thread thread = Thread.currentThread();
        Node node = new Node(null, null, thread);
        Node t = tail;
        if(t==null){
            if(compareAndSwapObject(tailOffset,null,node)){
                head=tail;
                return node;
            }
        }else{
            node.prev=t;
            if(compareAndSwapObject(tailOffset,t,node)){
                t.next=node;
                return node;
            }
        }
    }
}

/**
 * 从头部删除链表节点
 * */
public Node getNode(){
    for (;;){
        Node h=head;
        if(h==null)
            return null;
        if(h.next==null){
            tail=null;
        }
        if(compareAndSwapObject(headOffset,h,h.next)){
          return h;
        }
    }
}
/**
 * 获取链表节点数量
 * */
public int size(){
   int index=0;
    Node tem=head;
   while (tem!=null){
       index++;
       tem=tem.next;
   }
    return index;
}

private boolean compareAndSwapInt(long stateOffset,int expect,int update){
   return unsafe.compareAndSwapInt(this,stateOffset,expect,update);
}
private boolean compareAndSwapObject(long offset,Node expect,Node update){
    return unsafe.compareAndSwapObject(this,offset,expect,update);
}

}

Node
public class Node {

//指向前面节点的引用
public volatile Node  prev;

//指向后面节点的引用
public volatile Node  next;

//当前节点的线程
public volatile Thread thread;


public Node(Node prev, Node next, Thread thread) {
    this.prev = prev;
    this.next = next;
    this.thread = thread;
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值