1. 程式人生 > >執行緒與程序的分析

執行緒與程序的分析

執行緒Thread,多執行緒Multi-Thread

1、執行緒概念

什麼是執行緒:執行緒就是程式中單獨順序的流控制。執行緒本身不能執行,它只能用於程式中。

什麼是多執行緒:多執行緒則指的是在單個程式中可以同時執行多個不同的執行緒執行不同的任務.

      執行緒是程式內的順序控制流,只能使用分配給程式的資源和環境。

      多執行緒程式設計的目的,就是"最大限度地利用CPU資源",當某一執行緒的處理不需要佔用CPU而只和I/O等資源打交道時,讓需要佔用CPU資源的其它執行緒有機會獲得CPU資源。從根本上說,這就是多執行緒程式設計的最終目的。

單執行緒:當程式啟動執行時,就自動產生一個執行緒,主方法main就在這個主執行緒上執行;

Java中如果我們自己沒有產生執行緒,那麼系統就會給我們產生一個執行緒(主執行緒,main方法就在主執行緒上執行),我們的程式都是由執行緒來執行的。

2、程序:執行中的程式(程式是靜態的概念,程序是動態的概念),看windows工作管理員裡的程序。

3、程序與執行緒的區別:

      多個程序的內部資料和狀態都是完全獨立的,而多執行緒是共享一塊記憶體空間和一組系統資源,有可能互相影響.
      執行緒本身的資料通常只有暫存器資料,以及一個程式執行時使用的堆疊,所以執行緒的切換比程序切換的負擔要小。

4、多執行緒:一個程序可以包含一個或多個執行緒;   一個程式實現多個程式碼同時交替執行就需要產生多個執行緒;   CPU隨機的抽出時間,讓我們的程式一會做這件事情,一會做另外一件事情

      同其他大多數程式語言不同,Java內建支援多執行緒程式設計(multithreaded programming)。多執行緒程式包含兩條或兩條以上併發執行的部分,把程式中每個這樣的部分都叫作一個執行緒(thread)。每個執行緒都有獨立的執行路徑,因此多執行緒是多工處理的一種特殊形式。
      多工處理被所有的現代作業系統所支援。然而,多工處理有兩種截然不同的型別:基於程序的和基於執行緒的。

      1)基於程序的多工處理是更熟悉的形式。程序(process)本質上是一個執行的程式。因此基於程序的多工處理的特點是允許你的計算機同時執行兩個或更多的程式。舉例來說,基於程序的多工處理使你在運用文字編輯器的時候可以同時執行Java編譯器。在基於程序的多工處理中,程式是排程程式所分派的最小程式碼單位。
      2)而在基於執行緒(thread-based)的多工處理環境中,執行緒是最小的執行單位。這意味著一個程式可以同時執行兩個或者多個任務的功能。例如,一個文字編輯器可以在列印的同時格式化文字。

      多執行緒程式比多程序程式需要更少的管理費用。程序是重量級的任務,需要分配給它們獨立的地址空間。程序間通訊是昂貴和受限的。程序間的轉換也是很需要花費的。另一方面,執行緒是輕量級的選手。它們共享相同的地址空間並且共同分享同一個程序。執行緒間通訊是便宜的,執行緒間的轉換也是低成本的。

      多執行緒可幫助你編寫出CPU最大利用率的高效程式,使得空閒時間保持最低。這對Java執行的互動式的網路互連環境是至關重要的,因為空閒時間是公共的。例如,網路的資料傳輸速率遠低於計算機處理能力,而本地檔案系統資源的讀寫速度也遠低於CPU的處理能力。當然,使用者輸入也比計算機慢很多。在傳統的單執行緒環境中,程式必須等待每一個這樣的任務完成以後才能執行下一步—儘管CPU有很多空閒時間。多執行緒使你能夠獲得並充分利用這些空閒時間。

5、Java執行緒的實現

      在Java中通過run方法為執行緒指明要完成的任務,有兩種技術來為執行緒提供run方法。
      1)繼承Thread類並重寫run方法。
      2)通過定義實現Runnable介面的類進而實現run方法。

第一種方式:繼承Thread類:

  1. publicclass ThreadTest  
  2. {  
  3.     publicstaticvoid main(String[] args)  
  4.     {  
  5.         Thread1 t1 = new Thread1();  
  6.         t1.start();  
  7.     }  
  8. }  
  9. class Thread1 extends Thread  
  10. {  
  11.     @Override
  12.     publicvoid run()  
  13.     {  
  14.         for(int i = 0;i<100;i++)  
  15.         {  
  16.             System.out.println("hello:"+ i );  
  17.         }  
  18.     }  
  19. }  

      將我們希望執行緒執行的程式碼放到run方法中,然後通過start方法來啟動執行緒,start方法首先為執行緒的執行準備好系統資源,然後再去呼叫run方法。當某個類繼承了Thread類之後,該類就叫做一個執行緒類。

      兩個執行緒:

  1. publicclass ThreadTest  
  2. {  
  3.     publicstaticvoid main(String[] args)  
  4.     {  
  5.         Thread1 t1 = new Thread1();  
  6.         Thread2 t2 = new Thread2();  
  7.         t1.start();  //這裡絕對不能寫成t1.run();
  8.         t2.start();  //這裡絕對不能寫成t2.run();
  9.     }  
  10. }  
  11. class Thread1 extends Thread  
  12. {  
  13.     @Override
  14.     publicvoid run()  
  15.     {  
  16.         for(int i = 0;i<100;i++)  
  17.         {  
  18.             System.out.println("hello:"+ i );  
  19.         }  
  20.     }  
  21. }  
  22. class Thread2 extends Thread  
  23. {  
  24.     publicvoid run()  
  25.     {  
  26.         for(int i = 0;i<100;i++)  
  27.         {  
  28.             System.out.println("world welcome:"+ i );  
  29.         }  
  30.     }  
  31. }  


一個程序至少包含一個執行緒;對於單核CPU來說,某一時刻只能有一個執行緒在執行(微觀序列),從巨集觀角度來看,多個執行緒在同時執行(巨集觀並行);對於雙核或雙核以上的CPU來說,可以真正做到微觀並行。

第二種方式:實現Runable介面:

Runable只有一個方法run(),我們需要重寫此方法。(可以使用內部匿名類來實現)

  1. publicclass ThreadRunable  
  2. {  
  3.     publicstaticvoid main(String[] args)  
  4.     {  
  5.         Thread t1 = new Thread(new MyThread());  
  6.         Thread t2  = new Thread(new MyThread2());  
  7. //      Thread t1 = new Thread(new Runnable()  //使用內部匿名類
  8. //      {
  9. //          public void run()
  10. //          {
  11. //              for(int i = 0; i<100;i++)
  12. //              {
  13. //                  System.out.println(i);
  14. //              }
  15. //          }
  16. //      });
  17.         t1.start();  
  18.         t2.start();  
  19.     }  
  20. }  
  21. class MyThread implements Runnable  
  22. {  
  23.     @Override
  24.     publicvoid run()  
  25.     {  
  26.         for(int i = 0; i<100;i++)  
  27.         {  
  28.             System.out.println(i);  
  29.         }  
  30.     }  
  31. }  
  32. class MyThread2 implements Runnable  
  33. {  
  34.     @Override
  35.     publicvoid run()  
  36.     {  
  37.         for(int i = 0; i<100;i++)  
  38.         {  
  39.             System.out.println("hello" + i);  
  40.         }  
  41.     }  
  42. }  

使用實現Runnable介面的方式來實現執行緒,應該是啟動了Runnable中的run方法。

為什麼傳遞一個實現Runnable介面的類就可以呼叫其run方法呢,需要分析Thread的原始碼
6、Thread原始碼分析:

    1)通過類的定義:public class Thread implements Runnable           可知Thread類也實現了Runnable介面。所以Thread實現了Runnable介面中的run方法。

    2)構造方法:

  1. public Thread() {  
  2.     init(nullnull"Thread-" + nextThreadNum(), 0);  
  3.     }  
  4. public Thread(Runnable target) {  
  5.     init(null, target, "Thread-" + nextThreadNum(), 0);  
  6.     }  
  7. public Thread(ThreadGroup group, Runnable target) {  
  8.     init(group, target, "Thread-" + nextThreadNum(), 0);  
  9.     }  
  10. public Thread(String name) {  
  11.     init(nullnull, name, 0);  
  12.     }  

 private static int threadInitNumber;

private static synchronized int nextThreadNum() { return threadInitNumber++;    }

nextThreadNum()返回一個從0開始的整數,與Thread-字串連線,形成預設的執行緒名字。如果生成一個Thread物件:Thread t1 = new Thread(new MyThread());則t1.getName返回Thread-0,再生成一個Thread t2 = new Thread(new MyThread());則t2.getName為Thread-1,以此類推。

如果這樣定義Thread

  1. class Thread1 extends Thread  
  2. {  
  3.     public Thread1(String name)  
  4.     {  
super(name);}@Overridepublic void run(){for(int i = 0;i<100;i++){System.out.println("hello:"+ i );}}}構造Thread物件時:Thread1 t1 = new Thread1(“My Thread”);則t1.getName就為My Thread。 總結: 當生成一個執行緒物件時,如果沒有為其設定名字,那麼執行緒物件的名字將使用如下形式:Thread-number,該number將是自動增加的,並被所有的Thread物件所共享(因為它是static的成員變數)。 3)關於run方法
  1. publicvoid run() {  
  2. if (target != null) {  
  3.     target.run();  
  4. }  
  5.    }  

通過這個方法的原始碼,我們可以看出,此方法要麼什麼都不執行,要麼執行target的run方法,target是一個實現了Runnable介面的物件,通過public Thread(Runnable target)方式傳遞進來。通過init()方法,有一句this.target = target;private void init(ThreadGroup g, Runnable target, String name,long stackSize)當使用第一種方式來生成執行緒物件時,我們需要重寫run方法,因為Thread類的run方法此時什麼事情也不做。當使用第二種方式來生成執行緒物件時,我們需要實現Runnable介面的run方法,然後使用new Thread(new MyThread())(假如MyThread已經實現了Runnable介面)來生成執行緒物件,這時的執行緒物件的run方法就會呼叫MyThread類的run方法,這樣我們自己編寫的run方法就執行了。

7、總結 1).兩種方法均需執行執行緒的start方法為執行緒分配必須的系統資源、排程執行緒執行並執行執行緒的run方法。 2).在具體應用中,採用哪種方法來構造執行緒體要視情況而定。通常,當一個執行緒已繼承了另一個類時,就應該用第二種方法來構造,即實現Runnable介面。 3).執行緒的消亡不能通過呼叫一個stop()命令。而是讓run()方法自然結束。執行緒的停止(推薦的兩種方法):public class MyThread implements Runnable{ private boolean flag=true; public void run() { while (flag) {…} }public void stopRunning(){ flag=false;}}public class ControlThread{ private Runnable r=new MyThread(); private Thread t=new Thread(r); public void startThread() { t.start(); } publi void stopThread() { r.stopRunning();}}

8、執行緒的生命週期

執行緒的生命週期:一個執行緒從建立到消亡的過程。執行緒的生命週期可分為四個狀態:  1).建立狀態  2).可執行狀態  3).不可執行狀態  4). 消亡狀態執行緒狀態轉換圖:

1)建立狀態•當用new操作符建立一個新的執行緒物件時,該執行緒處於建立狀態。•處於建立狀態的執行緒只是一個空的執行緒物件,系統不為它分配資源

2.)可執行狀態•執行執行緒的start()方法將為執行緒分配必須的系統資源,安排其執行,並呼叫執行緒體—run()方法,這樣就使得該執行緒處於可執行( Runnable )狀態。•這一狀態並不是執行中狀態(Running ),因為執行緒也許實際上並未真正執行。

3)不可執行狀態當發生下列事件時,處於執行狀態的執行緒會轉入到不可執行狀態。•呼叫了sleep()方法;•執行緒呼叫wait方法等待特定條件的滿足•執行緒輸入/輸出阻塞

返回可執行狀態:•處於睡眠狀態的執行緒在指定的時間過去後•如果執行緒在等待某一條件,另一個物件必須通過notify()或notifyAll()方法通知等待執行緒條件的改變•如果執行緒是因為輸入/輸出阻塞,等待輸入/輸出完成

4)消亡狀態當執行緒的run方法執行結束後,該執行緒自然消亡。

9、執行緒優先順序

1) 執行緒的優先順序及其設定設定優先順序是為了在多執行緒環境中便於系統對執行緒的排程,優先順序高的執行緒將優先執行。一個執行緒的優先順序設定遵從以下原則:  –執行緒建立時,子繼承父的優先順序  –執行緒建立後,可通過呼叫setPriority()方法改變優先順序。  –執行緒的優先順序是1-10之間的正整數。  1 - MIN_PRIORITY,  10 – MAX_PRIORITY  5- NORM_PRIORITY

2) 執行緒的排程策略執行緒排程器選擇優先順序最高的執行緒執行。但是,如果發生以下情況,就會終止執行緒的執行。  •執行緒體中呼叫了yield()方法,讓出了對CPU的佔用權  •執行緒體中呼叫了sleep()方法, 使執行緒進入睡眠狀態  •執行緒由於I/O操作而受阻塞  •另一個更高優先順序的執行緒出現。  •在支援時間片的系統中,該執行緒的時間片用完。

10、執行緒資源使用問題:

  1. publicclass ThreadTest3  
  2. {  
  3. 相關推薦

    執行程序分析

    執行緒Thread,多執行緒Multi-Thread 1、執行緒概念 什麼是執行緒:執行緒就是程式中單獨順序的流控制。執行緒本身不能執行,它只能用於程式中。 什麼是多執行緒:多執行緒則指的是在單個程式中可以同時執行多個不同的執行緒執行不同的任務.       執行

    1、執行程序

    一、程序: 定義:  程序是具有一定功能的程式在一個數據集合上的執行過程,它是系統進行資源分配和排程管理的一個可併發執行的基本單位。 理解:        1、每個程序擁有獨立的程式碼和資料空間。    

    執行程序的總體區別

    程序和執行緒的總體區別 程序 什麼是程序? 程式的一個執行例項 正在執行的程式 核心觀點:擔當分配系統資源(cpu時間或記憶體)的實體。 程序就是一個程式在一個數據集上的一次動態執行過程。 程序由以下三部分組成: 1、程式:我們編寫的程式用來描述程序

    執行間的通訊方式以及執行程序的區別

    1、鎖機制      1.1 互斥鎖:提供了以排它方式阻止資料結構被併發修改的方法。      1.2 讀寫鎖:允許多個執行緒同時讀共享資料,而對寫操作互斥。      1.3 條

    執行程序的區別聯絡

    1.定義   程序是具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的一個獨立單位. 執行緒是程序的一個實體,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位.執行緒自己基本上不擁有系統資源,只擁有一點在執行中必不可少的資源

    2.多執行-區分執行程序

    執行緒與程序 程序是計算機中的程式關於某資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位,是作業系統結構的基礎,在早期面向程序設計的計算機結構中,程序是程式的基本執行實體,在當代面向執行緒的計算機結構中,程序是執行緒的容器,程式是指令資料及其組織形式的描述,程序是程式的實體。windows中ex

    一次性區分執行程序在程式執行中的關係

    一直不能區分執行緒是CPU排程和分配的基本單位,程序是作業系統進行資源分配的最小單位的關係,下面這段話是從一片博文中摘抄的,讓我幾周以來的模糊認識一下子清晰起來,希望對大家理解有幫助,原博文地址在前一篇文章中已貼出,好文章讀起來真是受益匪淺,原文如下:  執行緒是CPU排程和分配的基本單位,一定

    執行程序,如兄如父如homie?

    顯然這是一個在面試中的高頻問題,每次碰上,第一反應都是欣喜,心想這題我見過,程序就是一個程式嘛,可以由一個或多個執行緒組成。然後和麵試官尷尬對視三十秒,七零八落說一通,腦海裡很多想法,卻沒法有條理的串在一起,自己也覺得不滿意。還是沉下心,好好整理一下。     在此之前,先明白幾個概

    菜雞的Java筆記 第三十七 執行程序

    執行緒與程序        執行緒與程序的區別                最早的的時候DOS 系統有一個特點:只要電腦有病毒,

    執行程序的聯絡,執行的優缺點。

    程序概念   程序是表示資源分配的基本單位,又是排程執行的基本單位。例如,使用者執行自己的程式,系統就建立一個程序,併為它分配資源,包括各種表格、記憶體空間、磁碟空間、I/O裝置等。然後,把該程序放人程序的就緒佇列。程序排程程式選中它,為它分配CPU以及其它有關資源,該程序

    python之《執行程序

    執行緒:是作業系統最小的排程單位,是一串指令的集合 程序:eg:QQ要以一個整體的形式暴露給作業系統管理,裡面包含對各種資源的呼叫,記憶體對各種資源管理的集合叫做程序 程序操作cpu必須先建立一個執行緒,只有執行緒才能操作cpu 所一在同一程序中的執行緒是共享同一片記憶體空間的,但是兩個執行緒不能在同一

    物件、類和例項&&執行程序

    物件、類和例項&&執行緒與程序 前言: 前幾天早上Big-man和自己的一位同事,爭論一個問題,這個問題就是物件是什麼?。她的爭論是”物件是類的例項化”, 而Big-man卻是

    執行程序的區別優缺點

        [1]程序        1.每建立一個程序,核心都會給這個程序分配資源(記憶體.cpu...)。         2.程序是系統分配資源的最小單位。  &nbs

    執行程序最通俗易懂的解釋(附面試題答案)

    程序和執行緒都是一個時間段的描述,是CPU工作時間段的描述。一、CPU+RAM+各種資源(比如顯示卡,光碟機,鍵盤,GPS, 等等外設)構成我們的電腦,但是電腦的執行,實際就是CPU和相關暫存器以及RAM之間的事情。二、CPU太快,太快,太快了,暫存器僅僅能夠追的上他的腳步,RAM和別的掛在各總線上的裝置完全

    什麼是類,什麼是虛擬機器,和記憶體CPU有什麼關係......執行程序的關係

    今天我公司一大神去面試小朋友,從他的問話交流中感覺得出來.他已經達一種超出寫程式碼的層次,可能已經到了架構師以上的級別吧. 而問的一些問題,卻是我早早準備面試題之外的話題.雖然我知道他問的這些是想了解我哪方面,可是我已經不知道如何去回答了. 特別是心裡本來就對JAVA的理解

    C++面試題二---執行程序

    經典的執行緒與程序的面試題 1、 執行緒的基本概念、執行緒的基本狀態及狀態之間的關係? 概念:執行緒是程序中執行運算的最小單位,是程序中的一個實體,是被系統獨立排程和分派的基本單位,執行緒自己不擁有系統資源,只擁有一點在執行中必不可少的資源,但它可與同

    執行程序

    這麼解釋問題吧:1。單程序單執行緒:一個人在一個桌子上吃菜。2。單程序多執行緒:多個人在同一個桌子上一起吃菜。3。多程序單執行緒:多個人每個人在自己的桌子上吃菜。多執行緒的問題是多個人同時吃一道菜的時候容易發生爭搶,例如兩個人同時夾一個菜,一個人剛伸出筷子,結果伸到的時候已經被夾走菜了。。。此時就必須等一個人

    做一個好前端必須要知道的事——瀏覽器的執行程序

    瀏覽器是指chrome,沒心情關心其他的 程序和執行緒 直接上總結,想深入理解的可以查閱文末的連結 程序是作業系統進行資源分配和排程的一個獨立單位,是應用程式執行的載體 執行緒是程式執行中一個單一的順序控制流程,是程式執行流的最小單元,是處理器排程和分派的基本單位

    iOS 中執行程序的區別

           執行緒程序的區別和聯絡     (1)一個執行緒只能屬於一個程序,而一個程序可以有多個執行緒,但至少有一個執行緒。執行緒是作業系統可識別的最小執行和排程單位。    (2)資源分

    執行程序 計算密集型 IO密集型

    執行緒與程序:   執行緒和程序通常都有一個主線/程序的負責分配任務和其他子線/程序負責執行任何。   多程序的優點在於一個子程序掛了,不會影響其他程序(主程序掛了就全掛了),但是其建立的代價較大,Apache採用的就是多程序機制;   而多執行緒一般要比