通过AQS自定义锁

来源:互联网 发布:45度网络广播电台 编辑:程序博客网 时间:2024/06/04 17:42

自定义独占锁只需要定义一个非公开的内部类继承AbstractQueuedSynchronizer类重写tryAcquire和tryRelease就可以了。

package multi;


import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class MyLock implements Lock{

    private final Sync sync;
    
    public MyLock(){
        sync = new Sync();
    }
    
    private class Sync extends AbstractQueuedSynchronizer{

        private static final long serialVersionUID = 4206028266355265870L;

        protected boolean tryAcquire(int arg) {
            
            int state = getState();
            Thread currentThread = Thread.currentThread();
            if(state == 0){
                if(compareAndSetState(state, arg)){
                    
                    setExclusiveOwnerThread(currentThread);
                    return true;
                }
            }
            
            if(currentThread == getExclusiveOwnerThread()){
                state = getState();
                setState(state + 1);
                return true;
            }
            return false;
            
        }
        
        
        protected boolean tryRelease(int arg) {
            
            if(Thread.currentThread() != getExclusiveOwnerThread()){
                throw new RuntimeException();
            }
            
            int state = getState() - arg;
            
            if(state  < 0 ){
                throw new RuntimeException();
            }
            
            boolean flag = false;
            
            if(state == 0){
                // 先设定当前线程为空后,再设定state值
                setExclusiveOwnerThread(null);
                flag = true;
            }
            
            setState(state);
            return flag;
            
        }
        
        protected Condition newCondition() {
            return new ConditionObject();
        }
        
    }
    
    @Override
    public void lock() {
        sync.acquire(1);
        
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
        
    }

    @Override
    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        
        return sync.tryAcquireNanos(1, unit.toNanos(time));
    }

    @Override
    public void unlock() {
        sync.release(1);
        
    }

    @Override
    public Condition newCondition() {
    
        return sync.newCondition();
    }

}


测试代码:

package multi;

public class Main {
    
    private int count;
    
    private MyLock lock = new MyLock();
    
    private void incr(){
        lock.lock();
        try{
            count++;
            
            lock.lock();
            
            try{
                count++;
            }finally{
                lock.unlock();
            }
        }finally{
            lock.unlock();
        }
        
    }
    
    public static void main(String[] args) throws InterruptedException {
        Main main = new Main();
        Thread  thread1 = new Thread(new Runnable(){

            @Override
            public void run() {
                for(int i = 0;i < 100000;i++){
                    main.incr();
                }
            }
            
        },"thread1");
        
        Thread  thread2 = new Thread(new Runnable(){

            @Override
            public void run() {
                for(int i = 0;i < 100000;i++){
                    main.incr();
                }
            }
            
        },"thread2");
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        
        System.out.println(main.count);
        
        
    }

}



原创粉丝点击