多线程学习七——实现独占锁

独占锁:有且只有一个线程能持有该锁,而且获得锁的线程也只能获得一次,不能获得多次

package day1;

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 MutexLock implements Lock {
    // 静态内部类,自定义同步器
    private static class Sync extends AbstractQueuedSynchronizer {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        // 是否处于占用状态
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }

        // 当状态为0的时候获取锁
        public boolean tryAcquire(int acquires) {
            //独占锁实现的关键,只有锁没有被占时才可能获得锁
            if (compareAndSetState(0, 1)) {
                //获得锁成功,设置拥有锁的线程为当前线程
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        // 释放锁,将状态设置为0
        protected boolean tryRelease(int releases) {
            if (getState() == 0)
                throw new IllegalMonitorStateException();
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        // 返回一个Condition,每个condition都包含了一个condition队列
        Condition newCondition() {
            return new ConditionObject();
        }
    }

    // 仅需要将操作代理到Sync上即可
    private final Sync sync = new Sync();

    public void lock() {
        sync.acquire(1);
    }

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

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

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

    public boolean isLocked() {
        return sync.isHeldExclusively();
    }

    public boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }

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

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

如果是一个回调方法的话,会形成死锁,如:

package day1;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MutexLockTest {
    private static MutexLock lock = new MutexLock();
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(2);
        executor.execute(new Thread1());
        executor.shutdown();
    }

    static class Thread1 implements Runnable {

        @Override
        public void run() {
            try {
                lock.lock();
                lock.lock();
                System.out.println(sumNum(1,100));
            } finally {
                lock.unlock();
            }

        }
        int sum = 0;
        public int sumNum(int start,int end) {
            if(start <=end) {
                sum = sum+start;
                sumNum(start+1,end);
            }
            return sum;
        }

    }
}

猜你喜欢

转载自blog.csdn.net/shidebin/article/details/82628001