1. 程式人生 > >十一、併發程式設計之Lock介面的認識與使用

十一、併發程式設計之Lock介面的認識與使用

1、認識

在這裡插入圖片描述

2、優勢

  • Lock 類似於synchronized,具有相同的互斥性和記憶體可見性,但是更加靈活,加鎖和放鎖可以由使用者自己確定,Synchronized不需要顯示地獲取和釋放鎖,簡單
  • 可以方便的實行公平性
  • 非阻塞的獲取鎖
  • 能被中斷的獲取鎖,synchronized鎖可能出現異常而導致中斷,無法釋放鎖,但是通過使用lock,可以直接將lock放在異常finally中,強制釋放鎖。
  • 超時獲取鎖

3、使用

public class Sequence {
	private int value  ;
	Lock lock =
new ReentrantLock(); public int getNext() { //lock放在這裡是鎖不住的,所有執行緒得共用一把鎖才鎖的住,所有鎖得放外邊 //Lock lock = new ReentrantLock(); lock.lock();//獲取鎖 int a = value++; lock.unlock();//釋放鎖 return a; } public static void main(String[] args) { Sequence sequence = new Sequence(); //第一個執行緒 new Thread(new
Runnable() { @Override public void run() { while(true) { System.out.println(Thread.currentThread().getName()+" ----->"+sequence.getNext()); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); //第二個執行緒
new Thread(new Runnable() { @Override public void run() { while(true) { System.out.println(Thread.currentThread().getName()+" ----->"+sequence.getNext()); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); //第三個執行緒 new Thread(new Runnable() { @Override public void run() { while(true) { System.out.println(Thread.currentThread().getName()+" ----->"+sequence.getNext()); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } }

4、實現一個普通的鎖

public class MyLock implements Lock{
	private boolean isLocked = false;
	//加鎖
	@Override
	public synchronized void lock() {
		// 第一個執行緒進來不等待,其他線性進來等待
		while(isLocked) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		isLocked = true;
	}
	//釋放鎖
	@Override
	public synchronized void unlock() {
		isLocked = false;//釋放鎖
		notifyAll();//喚醒其他執行緒
	}
	//中斷鎖
	@Override
	public void lockInterruptibly() throws InterruptedException {

	}

	@Override
	public boolean tryLock() {
		return false;
	}

	@Override
	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
		return false;
	}

	@Override
	public Condition newCondition() {
		return null;
	}
}
public class Sequence {
	private MyLock lock = new MyLock();
	private int value;
	
	public  int getNext() {
		lock.lock();//獲取鎖
		value++;
		lock.unlock();//釋放鎖
		return value;
	}

	public static void main(String[] args) {
		Sequence sequence = new Sequence();
		//第一個執行緒
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(true) {
					System.out.println(Thread.currentThread().getName()+"      ----->"+sequence.getNext());
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
		
		//第二個執行緒
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(true) {
					System.out.println(Thread.currentThread().getName()+"      ----->"+sequence.getNext());
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
		//第三個執行緒
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(true) {
					System.out.println(Thread.currentThread().getName()+"      ----->"+sequence.getNext());
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
	}
}

5、實現一個重入鎖

public class MyLock implements Lock {
	private boolean isLocked = false;//是否鎖住
	private Thread lockBy = null;//拿到鎖的執行緒
	private int lockCount = 0;//鎖的數量

	@Override
	public synchronized void lock() {
		Thread currentThread = Thread.currentThread(); // 當前執行緒
		while (isLocked && currentThread != lockBy)//鎖住了並且執行緒不等於當前執行緒
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		isLocked = true;
		lockBy = currentThread;
		lockCount ++; // 1   2  3拿到鎖的數量想加
	}
	
	@Override
	public synchronized void unlock() {
		if(lockBy == Thread.currentThread()) {
			lockCount --;  //2  1  0
			if(lockCount == 0) {//釋放所有鎖之後
				notify();
				isLocked = false;
			}
		}
	}

	@Override
	public void lockInterruptibly() throws InterruptedException {
		
	}

	@Override
	public boolean tryLock() {
		return false;
	}

	@Override
	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
		return false;
	}

	@Override
	public Condition newCondition() {
		return null;
	}
}
public class Demo {
	MyLock lock = new MyLock();
	public void a() {
		lock.lock();
		System.out.println("a");
		b();
		lock.unlock();
	}
	public void b() {
		lock.lock();
		System.out.println("b");
		c();
		lock.unlock();
	}
	public void c() {
		lock.lock();
		System.out.println("c");
		lock.unlock();
	}
	public static void main(String[] args) {
		Demo d = new Demo();
		new Thread(new Runnable() {
			@Override
			public void run() {
				d.a();
			}
		}).start();
		new Thread(new Runnable() {
			@Override
			public void run() {
				d.b();
			}
		}).start();
	}
}