1. 程式人生 > >多執行緒解決視窗售票問題

多執行緒解決視窗售票問題

   如果用過迅雷的人,就會發現,迅雷的速度比普通的下載器下載速度要快。是它有單用的網速通道嗎?當然不是,這是因為迅雷開啟了多執行緒,加快了下載速度。

   什麼是程序?

   程序就是正在執行的程式。開啟QQ就是開啟了一個程序,當一個程序進入記憶體執行,就變成了一個程序。程序是處於執行過程中的程式。

   什麼是執行緒?

   執行緒是程序中的一個執行單元,一個程序可以有多個執行緒。360安全衛士,在開啟病毒查殺的同時也可以開啟垃圾清理,一個程式開啟多個任務,也就是開啟多個執行緒的表現。

   以前我們的CPU是單核的,執行緒不能同時進行,只能執行一個執行緒。所有執行緒輪流使用 CPU 的使用權,平均分配每個執行緒佔用 CPU 的時間。CPU會在各個程序之間高度切換。現在CPU有二核四核的,這樣就可以有多個執行緒同時程序。所以我們再看手機或電腦的時候,我們往往會關注是幾核的,多核的執行速度會比較快。

   建立執行緒的目的:

   是為了建立程式單獨執行的路徑,讓多部分程式碼實現同時執行。也就是說執行緒的建立並執行需要給定執行緒要執行的任務。

多執行緒定義方式:

     1、定義類實現Runnable介面。
     2、覆蓋介面中的run方法。。
     3、建立Thread類的物件
     4、將Runnable介面的子類物件作為引數傳遞給Thread類的建構函式。
     5、呼叫Thread類的start方法開啟執行緒。

這種方式去實現執行緒是比較好的,還有一種是繼承Thread類

     1 定義一個類繼承Thread。
     2 重寫run方法。
     3 建立子類物件,就是建立執行緒物件。
     4 呼叫start方法,開啟執行緒並讓執行緒執行,同時還會告訴jvm去呼叫run方法。

    需求:電影院賣票,我們用多執行緒模擬電影院的賣票過程。假設有兩個視窗正在售票編號為01-100,視窗一和視窗二正在賣票,本次電影的座位共100個(本場電影只能賣100張票)編號為01-100,現在實現:1、兩個視窗賣票 2.計算兩個視窗各自賣了多少張票,各自賣的票的編號3.實現兩個視窗輪流賣票

public static void main(String[] args) {
		//有100張票 編號為01-100
		List<String> li=new ArrayList<String>();
		for (int i = 1; i <=100; i++) {
			if(i<10){
				String s="0"+i;
				li.add(s);
			}else{
			li.add(i+"");
			}
		}
		// tickets t=new tickets();
	    //建立兩個Thread類物件,傳遞Runnable介面實現類
	        tickets t=new tickets(li);                     //3.建立實現類物件
	  		Thread t0 = new Thread(t,"視窗一");    //4.建立Thread類物件 ,並將runnable實現類作為引數
	  		Thread t1=new Thread(t,"視窗二");
	  		t0.start();
	  		t1.start();
		
	}

public class tickets implements Runnable {             // 建立多執行緒的方式:1實現Runnable介面
	private List<String> li; // 共享資料  票的編號01-100
	private int ticket = 100; // 共享資料

	// 利用建構函式載入初始資料
	public tickets(List<String> li) {
		this.li = li;
	}

	public tickets() {
		super();
	}// 空引數構造

	@Override
	public void run() {                           //2.重寫run方法
		 List<String> ticketNum =new ArrayList<String>();
		int count = 0; // 區域性資料是定義各自的計數
		while (true) { //
			synchronized (this) { // 同步程式碼塊 這裡加了鎖 安全機制
				if (ticket<=0) {
					System.out.println(Thread.currentThread().getName() + "賣了" + count + "張,票的編號為:"+ticketNum);
					return;
				}
				count++;
				ticket--;
				//---------------
				Random ra=new Random();
				int num = ra.nextInt(li.size()); //產生0-100的隨機數,作為索引
				ticketNum.add(li.get(num));  //根據索引來取集合中的資料           
				li.remove(num);  //因為取出來的票是不同的編號,取出一個就刪除一個,避免重複   
                       //兩個程序交替執行
				if(flag){
				   flag=true;
				   this.notify();//去喚醒另外一個程序
			     try {this.wait();} //本程序進行等待
			           catch (InterruptedException e) {	e.printStackTrace();}
			   }else{
				   flag=false;
				   this.notify(); //去喚醒另一個程序
				   try {this.wait();} //本程序等待
				       catch (InterruptedException e) {e.printStackTrace();} 
			   }	
			}
		}

	}


總結:其實生活中很多場景都可以執行到多執行緒,12306火車購票時我們可以網上購票,也可以視窗購票。執行緒是不安全的,但是速度快。我們加上同步程式碼塊的,加鎖機制後,保證了安全性,但是不可避免的降低速度。在Java中有很多類我們用的時候是不安全的,但是速度快。正是因為我們對於速度的考慮。