2013.11.07 ——— java线程之CLH队列锁

2013.11.07 ——— java线程之CLH队列锁
参考: http://blog.csdn.net/aesop_wubo/article/details/7533186

详细解释 见上面的链接,例子如下:

package com.lp.lock;

public interface Lock {
    void lock();
    void unLock();
}


package com.lp.lock;

public class QNode {
   public volatile boolean locked;
}

package com.lp.lock.clh;

import java.util.concurrent.atomic.AtomicReference;

import com.lp.lock.Lock;
import com.lp.lock.QNode;

public class CLHLock implements Lock{
    AtomicReference<QNode> tail = new AtomicReference<QNode>(new QNode());//
    ThreadLocal<QNode> mPre;//当前线程的前一个qnode
    ThreadLocal<QNode> mNode;//当前线程的当前的qnode
    public CLHLock(){
        tail = new AtomicReference<QNode>(new QNode());
        mNode = new ThreadLocal<QNode>(){
            @Override
            protected QNode initialValue() {
                return new QNode();
            }
        };
        mPre = new ThreadLocal<QNode>(){
            @Override
            protected QNode initialValue() {
                return null;
            }
        };
    }
    /**
     * 
     */
    @Override
    public void lock() {
        QNode lNode = mNode.get();//得到当前线程的qnode
        lNode.locked = true;//设置为true 告诉其他线程 我准备获得锁
        QNode pNode = tail.getAndSet(lNode);//得到前一个获得锁的qnode 并将tail设置我当前qnode,这样下一个线程就会等待本线程释放锁之后 才会执行 形成了队列 己成为队列的尾部
        mPre.set(pNode);
        while(pNode.locked){//等待前一个获得锁的线程释放锁
//            System.out.println(Thread.currentThread().getName());
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            
        }
    }
    @Override
    public void unLock() {
        QNode lNode = mNode.get();//得到当前线程的qnode
        lNode.locked = false;//设置为false 告诉其他线程 我释放了锁
        mNode.set(mPre.get());//移除本节点 
    }
    
    
    
}


package com.lp.lock.clh;


import com.lp.lock.Lock;

public class TestCLHLock {
    public static void main(String[] args) {
        final Kfc kfc = new Kfc();
        for(int i=0;i<10;i++){
            new Thread("eat" + i){
                public void run() {
                    while(true){
                        kfc.eat();
                    }
                }
            }.start();
        }
    }
}

class Kfc{
    private final Lock lock = new CLHLock();
    private int i = 0;
    public void eat(){
        try {
            lock.lock();
            System.out.println(Thread.currentThread().getName() + ": " + --i);
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            lock.unLock();
        }
    }
    public void cook(){
        try {
            lock.lock();
            System.out.println(Thread.currentThread().getName() + ": " + ++i);
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            lock.unLock();
        }
    }
}



你可能感兴趣的:(java线程)