多執行緒(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 再向系統申請。