自己实现java锁

import java.lang.reflect.Field;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

import sun.misc.Unsafe;


/**
 * 简单的重入锁
 * @version 1.0
 * @author jimmyyong
 *
 */
public class SimpleReentrantLock {
    
    
    private volatile static Unsafe unsafe;
    
    /** state内存地址给cas操作用的*/
    private volatile static long stateoffset;
    private volatile static long headoffset;
    private volatile static long tailoffset;
    private volatile static long waitoffset;
    
    /** 锁的状态,不为0表示有线程占有锁*/
    public volatile int state;
    
    public volatile Node head = new Node();
    public volatile Node tail = head;

    
    SimpleReentrantLock(){
        
        
    }
    
    /**
     * 获取锁,可重入
     * @return true:获取锁成功   false:获取锁失败
     */
    public void lock(){
        //if(!tryAcquire(1))
            acquire(1);   
    }
    
    /**
     * 释放锁,可重入
     * @return true:获取锁成功   false:获取锁失败
     */
    public boolean unlock(){
        for(;;){
            if(setCASWait(head,2, 0)){
                if(state-1 == 0){
                    Node next = head.next;
                    if(next != null){
                        if(next.next != null){
                            head.next = next.next;
                        }
                        unsafe.unpark(next.thread);
                    }
                }
                state=state-1;
                setCASWait(head,0, 2);
                return true;
            }
        }
    }
    
    /**
     * 获取锁
     * @param i
     * @return
     */
    public void acquire(int i){
        for(;;){
            try{
                if(tryAcquire(1)){
                    
                    return;
                }
                Node node = new Node();
                node.thread = Thread.currentThread();
                
                if(addQueue(node)){
                    setCASWait(head,1, 2);
                    return;
                }
                LockSupport.park();
            }finally{
                //  ****
            }
        }
    }    
    
    
    /**
     * 尝试获取锁
     * @param 增量数字
     * @return 获取锁是否成功
     */
    public boolean tryAcquire(int i){
        if(setCASState(0,i)){
            return true;
        }
        return false;
    }
    
    /**
     * 添加等待队列
     * @param node
     * @return
     */
    public boolean addQueue(Node node){
        for(;;){
            if(setCASWait(head,2, 1)){
                if(tryAcquire(1)){
                    return true;
                }
                Node oldtail = tail;
                if(setCASTail(oldtail, node)){
                    oldtail.next = node;        // 竞技条件
                    setCASWait(head,1, 2);
                    return false;    
                }
            }
        }
    }
    
    /**
     * 操作堆外内存
     * @return
     */
    public static Unsafe getUnsafe(){
        Field f1;
        try {
            f1 = Unsafe.class.getDeclaredField("theUnsafe");
            f1.setAccessible(true);
            return (Unsafe) f1.get(null);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return null;
    }
    
    /**
     * cas赋值state
     * @param exche     判断值
     * @param update    更新值
     * @return true:表示修改成功,false修改失败
     */
    public boolean setCASState(int exche,int update){
        return unsafe.compareAndSwapInt(this, stateoffset, exche, update);
    }
    
    /**
     * cas赋值head
     * @param exche     判断值
     * @param update    更新值
     * @return true:表示修改成功,false修改失败
     */
    public boolean setCASHead(Node exche,Node update){
        return unsafe.compareAndSwapObject(this, headoffset, exche, update);
    }
    
    /**
     * cas赋值tail
     * @param exche     判断值
     * @param update    更新值
     * @return true:表示修改成功,false修改失败
     */
    public boolean setCASTail(Node exche,Node update){
        return unsafe.compareAndSwapObject(this, tailoffset, exche, update);
    }
    
    /**
     * cas赋值tail
     * @param exche     判断值
     * @param update    更新值
     * @return true:表示修改成功,false修改失败
     */
    public boolean setCASWait(Node obj,int exche,int update){
        return unsafe.compareAndSwapInt(obj, waitoffset, exche, update);
    }
    
    /** 给内存地址赋值 */
    static{
        unsafe = getUnsafe();
        try {
            stateoffset = unsafe.objectFieldOffset(SimpleReentrantLock.class.getField("state"));                
            headoffset = unsafe.objectFieldOffset(SimpleReentrantLock.class.getField("head"));    
            tailoffset = unsafe.objectFieldOffset(SimpleReentrantLock.class.getField("tail"));
            waitoffset = unsafe.objectFieldOffset(Node.class.getField("wait"));    
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }
    
    static class Node{
        /**1表示可释放锁 2都可以  3表示可获取锁 */
        public volatile int wait = 2;
        volatile Node next;
        volatile Thread thread;
    }
    
    
    public static void main(String[] args) throws InterruptedException {
        final SimpleReentrantLock  lock = new SimpleReentrantLock();
        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                lock.lock();
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("xieyong1");
                lock.unlock();
            }
        });
        
        Thread thread2 = new Thread(new Runnable() {
            public void run() {
                    lock.lock();
                    System.out.println("xieyong2");
                    lock.unlock();
            }
        });
        
        
        
        thread1.setName("xieyong1");
        thread2.setName("xieyong2");
        thread1.start();
        thread2.start();
        //thread4.start();
    }
    
}

 上面这锁还有些问题:效率问题,重入问题,有时间发布第二篇博客

posted @ 2014-06-23 10:08  JimmyYong  阅读(629)  评论(0编辑  收藏  举报