1. 程式人生 > >多執行緒(1)

多執行緒(1)

    動態的概念       執行緒是程序中的一條完整的執行的路徑。執行緒是程序中的一個任務線。      執行緒的特點:         1:執行緒不能獨立存在,必須在某一個程序中存活。         2:多個執行緒可以併發執行。         3:程序提供了一個執行緒生存的環境,程序中所有的任務(程式碼)都是依靠程序中的執行緒來完成的。         4:一個程序中至少要有一個執行緒。當然可以有多個執行緒。         5:當一個程序啟動的時候,會先啟動一個執行緒。這個執行緒稱為主執行緒。         6:執行緒是cpu進行排程執行的最小單位。         7:一個程序中的多個執行緒共享所在的程序的資源。

舉個栗子:     1:迅雷 :程序。迅雷中的每一個下載的任務線可以看作一個執行緒。     2:程序:高速公路。執行緒:車道。

程序和執行緒的關係:

1:程序可以獨立存在,是cpu 進行資源分配的最小單位。 2:執行緒是依賴於某一個程序的。是cpu進行排程執行的最小單位。 3:一個程序中至少有一個執行緒。如果一個程序中所有的執行緒都over了。程序也 over。 4:可以把執行緒看作輕量級的程序。啟動程序和銷燬程序是比較消耗系統資源的。在程序中啟動和銷燬一個執行緒消耗的系統資源要少。 5:程序和執行緒都是可以併發執行的。

單執行緒程式的問題

    1:一旦程式碼中存在阻塞的方法,那麼整個程序都將進入等待的狀態。等待將產生阻塞的原因消除掉,才能繼續執行。

多執行緒程式

    1:某一個執行緒被阻塞了,其他的執行緒不受任何的影響。 列:qq登入:     1:一個獨立的執行緒來繪製登入的動畫效果。     2:一個獨立的執行緒來監聽伺服器的反饋的資訊。一旦資訊回來,立馬處理。

執行緒的實現:

java 的jdk 中 定義了一個描述執行緒的類-->java.lang.Thread.

任何的一個執行緒的執行的主體,都對應這一段程式碼任務。

java 執行緒的實現:

首先在main 執行緒中去建立啟動我們自定義的執行緒。

1:繼承執行緒類。 2:實現java.lang.Runnable。 3: 實現一個Callable 介面。 jdk1.5 出現的。

利用執行緒實現來模擬火車票購票系統:

package com.bjsxt.thread0917;
/**
 * 繼承執行緒類的方式去 模擬火車站賣票
 * @author yhl
 *
 */
public class ThreadTicketTest {

	public static void main(String[] args) {
		//建立唯一的票務系統物件
		Ticket ticket = new Ticket();
		//建立售票員物件
		TicketSaler saler1 = new TicketSaler(ticket);
		//設定執行緒的名字
		saler1.setName("售票員-1");
		TicketSaler saler2 = new TicketSaler(ticket);
		saler2.setName("售票員-2");
		TicketSaler saler3 = new TicketSaler(ticket);
		saler3.setName("售票員-3");
		TicketSaler saler4 = new TicketSaler(ticket);
		saler4.setName("售票員-4");
		TicketSaler saler5 = new TicketSaler(ticket);
		saler5.setName("售票員-5");
		
		//啟動執行緒執行 jvm 會呼叫執行 run 方法。 不要自己去呼叫 run 方法。
		saler1.start();
		saler2.start();
		saler3.start();
		saler4.start();
		saler5.start();
		
	}

}

//票務系統的類  可以使用單例模式
class Ticket{
	//餘票
	private int count = 100;

	/**
	 * 賣票的行為
	 * @param count 本次出售幾張票
	 * @return  如果出票成功,返回true ,否則 返回 false。
	 */
	public boolean sale(int count){
//		try {
//			Thread.sleep(100);
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
		if(this.count >= count){
			this.count -= count;
			System.out.println(Thread.currentThread().getName() + "\t賣出了 "+ count +" 張票!餘票為:"+this.count);
			return true;
		}
		System.out.println(Thread.currentThread().getName() + " 出票失敗!餘票不足! " + "餘票為:"+ this.count);
		return false;
	}
}

//使用繼承執行緒類的方式 建立執行緒,模擬售票員 阿姨
class TicketSaler extends Thread{
	//持有被訪問的票務系統的引用。
	private Ticket ticket;
	public TicketSaler(Ticket ticket) {
		super();
		this.ticket = ticket;
	}
	//這樣寫,每建立一個售票員執行緒,就會建立一個獨立的票務系統。
	//	Ticket ticket = new Ticket();
	//run 方法就是當前執行緒 的任務的執行的主體
	public void run() {
		boolean result = ticket.sale(1);
		while(result){
			result = ticket.sale(1);
		}
	}
}

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
package com.bjsxt.thread0917;
/**
 * 實現 java.lang.Runnable 介面。
 * @author yhl
 *
 */
public class RunnableThreadTest {

	public static void main(String[] args) {
		TicketRunnable runnable = new TicketRunnable();
		
		//建立了5個執行緒物件,執行同一個runnable 的run 方法。訪問同一個票務系統。
		Thread sale1 = new Thread(runnable);
		sale1.setName("售票員-1");
		Thread sale2 = new Thread(runnable);
		sale2.setName("售票員-2");
		Thread sale3 = new Thread(runnable);
		sale3.setName("售票員-3");
		Thread sale4 = new Thread(runnable);
		sale4.setName("售票員-4");
		Thread sale5 = new Thread(runnable);
		sale5.setName("售票員-5");
		//呼叫 Thread 類的run 方法。 run 方法中會 呼叫 執行 runnable 例項的 run 方法。
		sale1.start();
		sale2.start();
		sale3.start();
		sale4.start();
		sale5.start();
	}

}


class TicketRunnable implements Runnable{
	//票務系統
	private Ticket ticket = new Ticket();
	//執行緒的主體程式碼
	public void run() {
		boolean result = ticket.sale(1);
		while(result){
			result = ticket.sale(1);
		}
	}
}


1:繼承執行緒類:     優點:容易理解。程式碼實現簡單。     缺點:不能繼承其他的類。多個執行緒物件共享同一個資料,處理稍微複雜(持有同一個物件的引用、單例(侷限性))。

2:實現java.lang.Runnable 介面     優點:可以再繼承其他的類。多個執行緒物件共享同一個資料處理比較容易。直接在 Runnable 的子類中 建立該例項物件即可。     缺點:理解稍微複雜(代理設計模式)。程式碼實現稍微的複雜。 瞭解: 作業系統具有建立程序,和程序中執行緒的權利。 jvm,程式是沒有許可權去建立程序和執行緒的。 java 中執行緒的建立,是向jvm申請,jvm 再向系統申請。

執行緒的宣告週期: