線程安全問題

線程安全問題

	在解決線程安全問題前要先知道什麼是線程.
	在我們計算機中會存在多個進程,而每個進程就是一個可執行程序,這些可執行程序的根本就是一塊代碼.我們一個進程可以有多個線程組成,至少會有一個線程,所以線程就是進程的最小單位,它也是一小塊代碼.
	那麼線程的作用是什麼:
		①可以將代碼中(軟件)的某些獨立的功能包裝起來,單獨作爲任務交給CPU處理
		②將需做的某個功能封裝成一個線程體,該線程可以獨立的獲得CPU分配的資源從而實現多功能同時運行
	這裏就是我們線程安全問題的關鍵,當我們把不同功能包裝成多個線程後,需要去訪問同一個對象,當前一個線程還未完成功能時下一個線程又進來了,這裏就會導致線程安全問題.
	那麼怎麼去解決它:
	1.同步代碼
	語法結構
	synchronized (同步監聽對象) {
		可能引發線程安全問題的代碼
	}
	這裏就相當於把代碼捆成一捆,線程只能一個完成後才能進入下一個,而上邊的同步監聽對象可以是任意的對象,但是要保證所有的線程共享一個同步監聽對象(也就是保證被同步監聽對象是被所有線程共享的),當然這裏也可以用this代替,最常用的就是類的字節碼對象 ( 對象名.class)
	這裏模擬一個多窗口買票的情況
	public class TicketThread extends Thread{
		private static int num = 50;
		public void run() {
			while(num>0){
				saleOne();
			}
		}
		// 寫一個方法:銷售一張票
		private void saleOne(){
		// 只應該同步銷售的一張票的操作代碼
			synchronized (TicketThread.class) {
			// 下面的代碼是銷售一張票,每賣一張票的前提判斷是否有票
				if(num>0){
					System.out.println(this.getName()+" 您的票號是:"+num);
					num--;
				}
			}
		}
	}
	2.同步方法
		1)、在需要被同步的方法上面加關鍵字  synchronized
		2)、加的位置 :在返回值類型的前面
		3)、如果是一個非static的方法,那麼同步監聽對象就是this;
		4)、如果是static修飾的方法,那麼同步監聽對象就是當前方法所在的類的字節碼對象
		public class TicketThread implements Runnable{
	private int num = 50;
		public void run() {
			while(num>0){
			saleOne();
			}
		}
		synchronized private void saleOne(){
			if(num>0){
				System.out.println("您的票號是:"+num);
				num--;
			}
		}
	}
	3.鎖機制
	在java中有這麼一個接口類Lock(可以在api文檔中查找),可以用它來解決線程安全問題       lock     unlock
	public class Ticket extends Thread {
		public Ticket(String name) {
			super(name);
		}
		static Lock lock = new ReentrantLock();//必須保證多個線程訪問的是同一把鎖
		static int num = 50;
		@Override
		public void run() {
			while(num > 0){   //循環判斷,是否有就賣
					lock.lock();
				try {
					if(num>0){   //判斷賣一張票的操作
						System.out.println(getName()+" 您的票號是:"+num);
						num--;
					}	
				} finally {
					lock.unlock();
				}	
			}	
		}
	}	
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章