Java线程:创建与启动
生活随笔
收集整理的這篇文章主要介紹了
Java线程:创建与启动
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Java線程:創建與啟動 一、定義線程 1、擴展java.lang.Thread類。 此類中有個run()方法,應該注意其用法: public void run() 如果該線程是使用獨立的?Runnable?運行對象構造的,則調用該?Runnable?對象的?run?方法;否則,該方法不執行任何操作并返回。 ? Thread?的子類應該重寫該方法。 2、實現java.lang.Runnable接口。 void?run() 使用實現接口?Runnable?的對象創建一個線程時,啟動該線程將導致在獨立執行的線程中調用對象的?run?方法。 方法?run?的常規協定是,它可能執行任何所需的操作。 二、實例化線程 1、如果是擴展java.lang.Thread類的線程,則直接new即可。 2、如果是實現了java.lang.Runnable接口的類,則用Thread的構造方法: Thread(Runnable target)?
Thread(Runnable target, String name)?
Thread(ThreadGroup group, Runnable target)?
Thread(ThreadGroup group, Runnable target, String name)?
Thread(ThreadGroup group, Runnable target, String name, long stackSize) 三、啟動線程 在線程的Thread對象上調用start()方法,而不是run()或者別的方法。 在調用start()方法之前:線程處于新狀態中,新狀態指有一個Thread對象,但還沒有一個真正的線程。 在調用start()方法之后:發生了一系列復雜的事情 啟動新的執行線程(具有新的調用棧); 該線程從新狀態轉移到可運行狀態; 當該線程獲得機會執行時,其目標run()方法將運行。 注意:對Java來說,run()方法沒有任何特別之處。像main()方法一樣,它只是新線程知道調用的方法名稱(和簽名)。因此,在Runnable上或者Thread上調用run方法是合法的。但并不啟動新的線程。 四、例子 1、實現Runnable接口的多線程例子 /**?
* 實現Runnable接口的類?
*?
* @author leizhimin 2008-9-13 18:12:10?
*/?
public?class?DoSomething?implements?Runnable {?
????private?String name;?
????public?DoSomething(String name) {?
????????this.name = name;?
????}?
????public?void?run() {?
????????for?(int?i = 0; i < 5; i++) {?
????????????for?(long?k = 0; k < 100000000; k++) ;?
????????????System.out.println(name +?": "?+ i);?
????????}?
????}?
} /**?
* 測試Runnable類實現的多線程程序?
*?
* @author leizhimin 2008-9-13 18:15:02?
*/?
public?class?TestRunnable {?
????public?static?void?main(String[] args) {?
????????DoSomething ds1 =?new?DoSomething("阿三");?
????????DoSomething ds2 =?new?DoSomething("李四");?
????????Thread t1 =?new?Thread(ds1);?
????????Thread t2 =?new?Thread(ds2);?
????????t1.start();?
????????t2.start();?
????}?
} 執行結果: 李四: 0?
阿三: 0?
李四: 1?
阿三: 1?
李四: 2?
李四: 3?
阿三: 2?
李四: 4?
阿三: 3?
阿三: 4?
Process finished with exit code 0 2、擴展Thread類實現的多線程例子 /**?
* 測試擴展Thread類實現的多線程程序?
*?
* @author leizhimin 2008-9-13 18:22:13?
*/?
public?class?TestThread?extends?Thread{?
????public?TestThread(String name) {?
????????super(name);?
????}?
????public?void?run() {?
????????for(int?i = 0;i<5;i++){?
????????????for(long?k= 0; k <100000000;k++);?
????????????System.out.println(this.getName()+" :"+i);?
????????}?
????}?
????public?static?void?main(String[] args) {?
????????Thread t1 =?new?TestThread("阿三");?
????????Thread t2 =?new?TestThread("李四");?
????????t1.start();?
????????t2.start();?
????}?
} 執行結果: 阿三 :0?
李四 :0?
阿三 :1?
李四 :1?
阿三 :2?
李四 :2?
阿三 :3?
阿三 :4?
李四 :3?
李四 :4?
Process finished with exit code 0 對于上面的多線程程序代碼來說,輸出的結果是不確定的。其中的一條語句for(long k= 0; k <100000000;k++);是用來模擬一個非常耗時的操作的。 五、一些常見問題 1、線程的名字,一個運行中的線程總是有名字的,名字有兩個來源,一個是虛擬機自己給的名字,一個是你自己的定的名字。在沒有指定線程名字的情況下,虛擬機總會為線程指定名字,并且主線程的名字總是mian,非主線程的名字不確定。 2、線程都可以設置名字,也可以獲取線程的名字,連主線程也不例外。 3、獲取當前線程的對象的方法是:Thread.currentThread(); 4、在上面的代碼中,只能保證:每個線程都將啟動,每個線程都將運行直到完成。一系列線程以某種順序啟動并不意味著將按該順序執行。對于任何一組啟動的線程來說,調度程序不能保證其執行次序,持續時間也無法保證。 5、當線程目標run()方法結束時該線程完成。 6、一旦線程啟動,它就永遠不能再重新啟動。只有一個新的線程可以被啟動,并且只能一次。一個可運行的線程或死線程可以被重新啟動。 7、線程的調度是JVM的一部分,在一個CPU的機器上上,實際上一次只能運行一個線程。一次只有一個線程棧執行。JVM線程調度程序決定實際運行哪個處于可運行狀態的線程。 眾多可運行線程中的某一個會被選中做為當前線程。可運行線程被選擇運行的順序是沒有保障的。 8、盡管通常采用隊列形式,但這是沒有保障的。隊列形式是指當一個線程完成“一輪”時,它移到可運行隊列的尾部等待,直到它最終排隊到該隊列的前端為止,它才能被再次選中。事實上,我們把它稱為可運行池而不是一個可運行隊列,目的是幫助認識線程并不都是以某種有保障的順序排列唱呢個一個隊列的事實。 9、盡管我們沒有無法控制線程調度程序,但可以通過別的方式來影響線程調度的方式。 原文鏈接:http://lavasoft.blog.51cto.com/62575/99151
Thread(Runnable target, String name)?
Thread(ThreadGroup group, Runnable target)?
Thread(ThreadGroup group, Runnable target, String name)?
Thread(ThreadGroup group, Runnable target, String name, long stackSize) 三、啟動線程 在線程的Thread對象上調用start()方法,而不是run()或者別的方法。 在調用start()方法之前:線程處于新狀態中,新狀態指有一個Thread對象,但還沒有一個真正的線程。 在調用start()方法之后:發生了一系列復雜的事情 啟動新的執行線程(具有新的調用棧); 該線程從新狀態轉移到可運行狀態; 當該線程獲得機會執行時,其目標run()方法將運行。 注意:對Java來說,run()方法沒有任何特別之處。像main()方法一樣,它只是新線程知道調用的方法名稱(和簽名)。因此,在Runnable上或者Thread上調用run方法是合法的。但并不啟動新的線程。 四、例子 1、實現Runnable接口的多線程例子 /**?
* 實現Runnable接口的類?
*?
* @author leizhimin 2008-9-13 18:12:10?
*/?
public?class?DoSomething?implements?Runnable {?
????private?String name;?
????public?DoSomething(String name) {?
????????this.name = name;?
????}?
????public?void?run() {?
????????for?(int?i = 0; i < 5; i++) {?
????????????for?(long?k = 0; k < 100000000; k++) ;?
????????????System.out.println(name +?": "?+ i);?
????????}?
????}?
} /**?
* 測試Runnable類實現的多線程程序?
*?
* @author leizhimin 2008-9-13 18:15:02?
*/?
public?class?TestRunnable {?
????public?static?void?main(String[] args) {?
????????DoSomething ds1 =?new?DoSomething("阿三");?
????????DoSomething ds2 =?new?DoSomething("李四");?
????????Thread t1 =?new?Thread(ds1);?
????????Thread t2 =?new?Thread(ds2);?
????????t1.start();?
????????t2.start();?
????}?
} 執行結果: 李四: 0?
阿三: 0?
李四: 1?
阿三: 1?
李四: 2?
李四: 3?
阿三: 2?
李四: 4?
阿三: 3?
阿三: 4?
Process finished with exit code 0 2、擴展Thread類實現的多線程例子 /**?
* 測試擴展Thread類實現的多線程程序?
*?
* @author leizhimin 2008-9-13 18:22:13?
*/?
public?class?TestThread?extends?Thread{?
????public?TestThread(String name) {?
????????super(name);?
????}?
????public?void?run() {?
????????for(int?i = 0;i<5;i++){?
????????????for(long?k= 0; k <100000000;k++);?
????????????System.out.println(this.getName()+" :"+i);?
????????}?
????}?
????public?static?void?main(String[] args) {?
????????Thread t1 =?new?TestThread("阿三");?
????????Thread t2 =?new?TestThread("李四");?
????????t1.start();?
????????t2.start();?
????}?
} 執行結果: 阿三 :0?
李四 :0?
阿三 :1?
李四 :1?
阿三 :2?
李四 :2?
阿三 :3?
阿三 :4?
李四 :3?
李四 :4?
Process finished with exit code 0 對于上面的多線程程序代碼來說,輸出的結果是不確定的。其中的一條語句for(long k= 0; k <100000000;k++);是用來模擬一個非常耗時的操作的。 五、一些常見問題 1、線程的名字,一個運行中的線程總是有名字的,名字有兩個來源,一個是虛擬機自己給的名字,一個是你自己的定的名字。在沒有指定線程名字的情況下,虛擬機總會為線程指定名字,并且主線程的名字總是mian,非主線程的名字不確定。 2、線程都可以設置名字,也可以獲取線程的名字,連主線程也不例外。 3、獲取當前線程的對象的方法是:Thread.currentThread(); 4、在上面的代碼中,只能保證:每個線程都將啟動,每個線程都將運行直到完成。一系列線程以某種順序啟動并不意味著將按該順序執行。對于任何一組啟動的線程來說,調度程序不能保證其執行次序,持續時間也無法保證。 5、當線程目標run()方法結束時該線程完成。 6、一旦線程啟動,它就永遠不能再重新啟動。只有一個新的線程可以被啟動,并且只能一次。一個可運行的線程或死線程可以被重新啟動。 7、線程的調度是JVM的一部分,在一個CPU的機器上上,實際上一次只能運行一個線程。一次只有一個線程棧執行。JVM線程調度程序決定實際運行哪個處于可運行狀態的線程。 眾多可運行線程中的某一個會被選中做為當前線程。可運行線程被選擇運行的順序是沒有保障的。 8、盡管通常采用隊列形式,但這是沒有保障的。隊列形式是指當一個線程完成“一輪”時,它移到可運行隊列的尾部等待,直到它最終排隊到該隊列的前端為止,它才能被再次選中。事實上,我們把它稱為可運行池而不是一個可運行隊列,目的是幫助認識線程并不都是以某種有保障的順序排列唱呢個一個隊列的事實。 9、盡管我們沒有無法控制線程調度程序,但可以通過別的方式來影響線程調度的方式。 原文鏈接:http://lavasoft.blog.51cto.com/62575/99151
轉載于:https://www.cnblogs.com/jadeboy/p/3870264.html
總結
以上是生活随笔為你收集整理的Java线程:创建与启动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个小老板从小公司创业开始做起的过程记录
- 下一篇: 初学Java ssh之Spring 第二