1. 程式人生 > >終於弄懂了晦澀難懂的條件鎖-condition lock

終於弄懂了晦澀難懂的條件鎖-condition lock

 
package com.cn.whu;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadConditionLook {

	/**
	 * @param args
	 */
	//create a user's Account,watch out the "static"
	private static Account account = new Account();
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ExecutorService executor = Executors.newFixedThreadPool(2);
		executor.execute(new DepositTask());
		executor.execute(new WithdrawTask());
		executor.shutdown();
		System.out.println("Thread 1\t\tThread 2\t\t\t\tBalance");
	}
	private static class Account{
		//create a new lock
		private static Lock lock = new ReentrantLock();
		//craete a condition
		private static Condition newDeposit = lock.newCondition();
		private int  balance =0;
		public int getBalance(){
			return balance;
		}
		public void withdraw(int mount){
			lock.lock();//Acqurie the lock
			try{
				while(balance<mount){
					System.out.println("\t\t\tWait for a deposit");
					newDeposit.await();
				}
				balance -=mount; 
				System.out.println("\t\t\tWithdraw "+mount+"\t\t\t\t\t"+getBalance());
			}catch(InterruptedException e){
				
			}finally{
				lock.unlock();
			}
		}
		public void depsoit(int mount){
			lock.lock();
			try{
				balance+=mount;
				System.out.println("Deposit "+mount+"\t\t\t\t\t\t\t\t"+getBalance());
				newDeposit.signalAll();
			}finally{
				lock.unlock();
			}
		}
	}
	//Task for deposit account;
	private static class DepositTask implements Runnable{

		@Override
		public void run() {
			// TODO Auto-generated method stub
			
			try{
				while(true){
					account.depsoit((int)(Math.random()*10)+1);
					Thread.sleep(1000);
				}
				
			}catch(InterruptedException e){
				
			}
			
			
		}
		
	}
	//Task for withdraw account
	private static class WithdrawTask implements Runnable{

		@Override
		public void run() {
			// TODO Auto-generated method stub
			try{
				while(true){
					account.withdraw((int)(Math.random()*10)+1);
					Thread.sleep(1000);
				}
			}catch(InterruptedException e){
				
			}
		}
		
	}
}


條件鎖其實就是一個普通的鎖加上了一個條件,如下面兩行程式碼

//create a new lockprivate static Lock lock = new ReentrantLock();

//craete a conditionprivate static Condition newDeposit = lock.newCondition();

,重要的不是表象,是為什麼需要這個條件鎖,假設你有一個銀行賬戶,密碼你和你老婆都知道,你負責存錢,你老婆負責取錢,對存錢和取錢的程式碼都加了鎖,所以是可以同步的。誒,平常存啊取的都挺好的,結果你倆矛盾了,你不去存錢,誒銀行發現你老婆仍然可以取,而且透支了,你願意不?銀行願意不?當然不願意,也許你馬上想到了,誒,我可以在取錢的時候加個條件去判斷下,如果夠取,那就讓這個執行緒來取錢,否則呢?關鍵是這個否則呢?把這個執行緒幹掉?不人道吧,讓人家自己過N年後來取?這也不人道啊,評啥不是你通知人家老公存錢了,老婆過來看看,看夠取不?誒,這個條件鎖他就是這個為別人考慮的東西,你老婆一旦發現錢不夠取了,他就打電話給你,嘿,小夥子,快點存錢,你說我有事,等會在存,等了很久,你存了一點,好,你在打電話給她,說,你可以去取取看,看過不,不夠在打電話給我,夠了直接取了就是。

微笑