1. 程式人生 > >多執行緒學習七——實現獨佔鎖

多執行緒學習七——實現獨佔鎖

獨佔鎖:有且只有一個執行緒能持有該鎖,而且獲得鎖的執行緒也只能獲得一次,不能獲得多次

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;
        }

    }
}