1. 程式人生 > >十三、併發程式設計之使用AQS重寫自己的鎖

十三、併發程式設計之使用AQS重寫自己的鎖

package com.roocon.thread.ta2;

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 MyLock2 implements Lock {
	private Helper helper = new Helper()
; private class Helper extends AbstractQueuedSynchronizer{ @Override protected boolean tryAcquire(int arg) { /** * 如果第一個執行緒進來,可以拿到鎖,因此我們可以返回true * 如果第二個執行緒進來,拿不到鎖,返回false, * 有種特例,如果當前進來的執行緒和佔用排它鎖的執行緒是同一個執行緒(重入),則允許可以拿到鎖,但是要更新狀態值 * */ Thread t = Thread.currentThread(); //如何判斷是第一個執行緒進來還是其他執行緒進來
int state = getState();//拿到狀態 if(state==0) {//如果狀態等於0 ,無狀態(初始狀態) if(compareAndSetState(0,arg)) {// 如果狀態等於0 ,將狀態設定為arg setExclusiveOwnerThread(t);//設定佔用排它鎖的執行緒是當前執行緒 return true; } }else if(getExclusiveOwnerThread()==t){// 重入 setState(state+1);//更新狀態值 return true; } return false
; } @Override protected boolean tryRelease(int arg) { //鎖的獲取和釋放肯定是一一對應的,那麼呼叫此方法的執行緒一定是當前執行緒,如果不是丟擲異常 if(Thread.currentThread()!=getExclusiveOwnerThread()) { throw new RuntimeException(); } int state = getState()-arg; boolean flag = false; if(state==0) {//狀態為0,釋放鎖 setExclusiveOwnerThread(null);////設定佔用排它鎖的執行緒為空 flag = true; } setState(state); return flag; } Condition newCondition() { return new ConditionObject(); } } @Override public void lock() { helper.acquire(1); } @Override public void lockInterruptibly() throws InterruptedException { helper.acquireInterruptibly(1); } @Override public boolean tryLock() { return helper.tryAcquire(1); } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return helper.tryAcquireNanos(1, unit.toNanos(time)); } @Override public void unlock() { helper.release(1); } @Override public Condition newCondition() { return helper.newCondition(); } }
public class Main {
	private int value;
	private MyLock2 lock =new MyLock2();
	public int next() {
		lock.lock();//加鎖
		try {
			Thread.sleep(1000);
			 value++;
		} catch (InterruptedException e) {
			throw new RuntimeException();
		} finally {
			lock.unlock();//解鎖
		}
		return value;
	}
	
	public void a() {
		lock.lock();
		System.out.println("a");
		b();
		lock.unlock();
	}
	public void b() {
		lock.lock();
		System.out.println("b");
		lock.unlock();
	}
	public static void main(String[] args) {
		Main m = new Main();
		//執行緒1
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(true) {
					//測試執行緒安全問題
					//System.out.println(Thread.currentThread().getName()+"----->"+m.next());
					// 測試執行緒重入
					m.a();
				}
			}
		}) .start();
		//執行緒2
//		new Thread(new Runnable() {
//			@Override
//			public void run() {
//				while(true) {
					//測試執行緒安全問題
//					System.out.println(Thread.currentThread().getName()+"----->"+m.next());
//				}
//			}
//		}) .start();
//		//執行緒3
//		new Thread(new Runnable() {
//			@Override
//			public void run() {
//				while(true) {
					//測試執行緒安全問題
//					System.out.println(Thread.currentThread().getName()+"----->"+m.next());
//				}
//			}
//		}) .start();
	}
}