java學習筆記之多線程(2)之線程安全

保證線程安全的三種方式

(1)同步代碼塊:synchronized (obj),鎖的必須是各線程共享的對象;
(2)同步方法: synchronized 方法,對自己加鎖 ==synchronized (this)
(3)同步鎖: (只介紹可重入鎖)
final ReentrantLock lock=new ReentrantLock(); 
加鎖:調用lock()方法;釋放: 調用unlock()方法; 
public  void drawmoney(double num)
	{//同步代碼塊;
<span style="white-space:pre">	</span>synchronized(obj){
		if(num<getBalance())
		{
			System.out.println(Thread.currentThread().getName()+" succeed!");
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			setBalance(getBalance()-num);
			System.out.println(Thread.currentThread().getName()+" your balance is:"+getBalance());
			
		}
		else
		{
			System.out.println(Thread.currentThread().getName()+" sorry,your balance is insufficient!");
			System.out.println(Thread.currentThread().getName()+" your balance is:"+getBalance());
		}
<span style="white-space:pre">		</span>  }//自動解鎖
	}

//同步方法
public synchronized void drawmoney(double num)
	{
		if(num<getBalance())
		{
			System.out.println(Thread.currentThread().getName()+" succeed!");
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			setBalance(getBalance()-num);
			System.out.println(Thread.currentThread().getName()+" your balance is:"+getBalance());
			
		}
		else
		{
			System.out.println(Thread.currentThread().getName()+" sorry,your balance is insufficient!");
			System.out.println(Thread.currentThread().getName()+" your balance is:"+getBalance());
		}
	}//自動解鎖
同步代碼塊和同步方法釋放同步監視器條件:
(1)當前線程同步代碼塊或同步方法執行結束;
(2)當前線程在同步代碼塊或同步方法中執行了break、return等語句終止了該同步代碼塊或同步方法的繼續執行;
(3)當前線程在同步代碼塊或同步方法中遇到未處理的error,exception導致同步代碼塊或同步方法異常結束;
(4)當前線程在同步代碼塊或同步方法執行過程中,程序執行了同步監視器對象的wait()方法,則當前線程暫停,釋 放同步監視器;
總而言之:同步代碼塊或同步方法執行結束或暫停,則釋放同步監視器!
注意:在同步代碼塊或同步方法中執行sleep方法不會釋放同步監視器
           sleep方法、wait方法會阻塞線程,但wait方法會釋放同步監視器
   sleep到時間自動甦醒,wait需要被喚醒;
   yield是線程讓步,不會阻塞線程,從線程隊列中選取優先級最高線程

//同步鎖
public boolean transCount(Account de,double num)
	{       //加鎖
		lock.lock();
		try{
		if(drawmoney(num))
		{
			de.deposit(num);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("轉賬成功!");
			System.out.println("轉賬:"+de.getBalance());
			return true;
		}
		else
		{
			System.out.println("轉賬失敗!");
			return false;
		}
		}finally
{ <span style="white-space:pre">		</span>    //釋放
		    lock.unlock();
		}
	}
	public void deposit(double num)
	{
		lock.lock();
		try{
		setBalance(getBalance()+num);
		}finally{
			lock.unlock();
		}
	}
	
	
}


發佈了50 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章