Java 線程學(xué)習(xí)(1)
一、定義線程
1、擴(kuò)展java.lang.Thread類。
此類中有個(gè)run()方法,應(yīng)該注意其用法:
public void run()
如果該線程是使用獨(dú)立的
2、實(shí)現(xiàn)java.lang.Runnable接口。
void run()
使用實(shí)現(xiàn)接口
二、實(shí)例化線程
1 Thread類實(shí)例化
直接new即可
2 Runnable實(shí)例化
需要用Thread的構(gòu)造函數(shù)實(shí)例化
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)
是個(gè)簡(jiǎn)單的多線程程序。run()和start()是大家都很熟悉的兩個(gè)方法。把希望并行處理的代碼都放在run()中;start()用于自動(dòng)調(diào)用 run(),這是JAVA的內(nèi)在機(jī)制規(guī)定的。并且run()的訪問(wèn)控制符必須是public,返回值必須是void(這種說(shuō)法不準(zhǔn)確,run()沒(méi)有返回 值),run()不帶參數(shù)。
三、實(shí)例化代碼
Thread實(shí)例化線程
create thread1
create thread2
create thread3
線程 1:計(jì)數(shù) 1
線程 1:計(jì)數(shù) 2
create thread4
線程 1:計(jì)數(shù) 3
線程 2:計(jì)數(shù) 1
線程 1:計(jì)數(shù) 4
線程 2:計(jì)數(shù) 2
線程 2:計(jì)數(shù) 3
線程 2:計(jì)數(shù) 4
線程 2:計(jì)數(shù) 5
線程 3:計(jì)數(shù) 1
線程 3:計(jì)數(shù) 2
線程 3:計(jì)數(shù) 3
create thread5
線程 3:計(jì)數(shù) 4
線程 4:計(jì)數(shù) 1
線程 4:計(jì)數(shù) 2
線程 4:計(jì)數(shù) 3
線程 4:計(jì)數(shù) 4
線程 4:計(jì)數(shù) 5
線程 3:計(jì)數(shù) 5
線程 1:計(jì)數(shù) 5
線程 5:計(jì)數(shù) 1
線程 5:計(jì)數(shù) 2
線程 5:計(jì)數(shù) 3
線程 5:計(jì)數(shù) 4
線程 5:計(jì)數(shù) 5
Runnable實(shí)例化代碼
如果類繼承了別的類,就不能繼承 Thread 了,就要實(shí)現(xiàn) Runnable 接口了
在線程的Thread對(duì)象上調(diào)用start()方法,而不是run()或者別的方法。
在調(diào)用start()方法之前:線程處于新?tīng)顟B(tài)中,新?tīng)顟B(tài)指有一個(gè)Thread對(duì)象,但還沒(méi)有一個(gè)真正的線程。
在調(diào)用start()方法之后:發(fā)生了一系列復(fù)雜的事情
啟動(dòng)新的執(zhí)行線程(具有新的調(diào)用棧);
該線程從新?tīng)顟B(tài)轉(zhuǎn)移到可運(yùn)行狀態(tài);
當(dāng)該線程獲得機(jī)會(huì)執(zhí)行時(shí),其目標(biāo)run()方法將運(yùn)行。
注意:對(duì)Java來(lái)說(shuō),run()方法沒(méi)有任何特別之處。像main()方法一樣,它只是新線程知道調(diào)用的方法名稱(和簽名)。因此,在Runnable上或者Thread上調(diào)用run方法是合法的。但并不啟動(dòng)新的線程。
四、補(bǔ)充說(shuō)明
1、線程的名字,一個(gè)運(yùn)行中的線程總是有名字的,名字有兩個(gè)來(lái)源,一個(gè)是虛擬機(jī)自己給的名字,
一個(gè)是你自己的定的名字。在沒(méi)有指定線程名字的情況下,虛擬機(jī)總會(huì)為線程指定名字,并且主線
程的名字總是mian,非主線程的名字不確定。
2、線程都可以設(shè)置名字,也可以獲取線程的名字,連主線程也不例外。
3、獲取當(dāng)前線程的對(duì)象的方法是:Thread.currentThread();
4、在上面的代碼中,只能保證:每個(gè)線程都將啟動(dòng),每個(gè)線程都將運(yùn)行直到完成。一系列線程以某
種順序啟動(dòng)并不意味著將按該順序執(zhí)行。對(duì)于任何一組啟動(dòng)的線程來(lái)說(shuō),調(diào)度程序不能保證其執(zhí)行
次序,持續(xù)時(shí)間也無(wú)法保證。
5、當(dāng)線程目標(biāo)run()方法結(jié)束時(shí)該線程完成。
6、一旦線程啟動(dòng),它就永遠(yuǎn)不能再重新啟動(dòng)。只有一個(gè)新的線程可以被啟動(dòng),并且只能一次。一個(gè)
可運(yùn)行的線程或死線程可以被重新啟動(dòng)。
7、線程的調(diào)度是JVM的一部分,在一個(gè)CPU的機(jī)器上上,實(shí)際上一次只能運(yùn)行一個(gè)線程。一次只有一
個(gè)線程棧執(zhí)行。JVM線程調(diào)度程序決定實(shí)際運(yùn)行哪個(gè)處于可運(yùn)行狀態(tài)的線程。
眾多可運(yùn)行線程中的某一個(gè)會(huì)被選中做為當(dāng)前線程??蛇\(yùn)行線程被選擇運(yùn)行的順序是沒(méi)有保障的。
8、盡管通常采用隊(duì)列形式,但這是沒(méi)有保障的。隊(duì)列形式是指當(dāng)一個(gè)線程完成“一輪”時(shí),它移到
可運(yùn)行隊(duì)列的尾部等待,直到它最終排隊(duì)到該隊(duì)列的前端為止,它才能被再次選中。事實(shí)上,我們
把它稱為可運(yùn)行池而不是一個(gè)可運(yùn)行隊(duì)列,目的是幫助認(rèn)識(shí)線程并不都是以某種有保障的順序排列
唱呢個(gè)一個(gè)隊(duì)列的事實(shí)。
9、盡管我們沒(méi)有無(wú)法控制線程調(diào)度程序,但可以通過(guò)別的方式來(lái)影響線程調(diào)度的方式。
1、擴(kuò)展java.lang.Thread類。
此類中有個(gè)run()方法,應(yīng)該注意其用法:
public void run()
如果該線程是使用獨(dú)立的
Runnable
運(yùn)行對(duì)象構(gòu)造的,則調(diào)用該 Runnable
對(duì)象的 run
方法;否則,該方法不執(zhí)行任何操作并返回。Thread
的子類應(yīng)該重寫(xiě)該方法。2、實(shí)現(xiàn)java.lang.Runnable接口。
void run()
使用實(shí)現(xiàn)接口
Runnable
的對(duì)象創(chuàng)建一個(gè)線程時(shí),啟動(dòng)該線程將導(dǎo)致在獨(dú)立執(zhí)行的線程中調(diào)用對(duì)象的 run
方法。二、實(shí)例化線程
1 Thread類實(shí)例化
直接new即可
2 Runnable實(shí)例化
需要用Thread的構(gòu)造函數(shù)實(shí)例化
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)
是個(gè)簡(jiǎn)單的多線程程序。run()和start()是大家都很熟悉的兩個(gè)方法。把希望并行處理的代碼都放在run()中;start()用于自動(dòng)調(diào)用 run(),這是JAVA的內(nèi)在機(jī)制規(guī)定的。并且run()的訪問(wèn)控制符必須是public,返回值必須是void(這種說(shuō)法不準(zhǔn)確,run()沒(méi)有返回 值),run()不帶參數(shù)。
三、實(shí)例化代碼
Thread實(shí)例化線程
public class FirstThread extends Thread{
int count= 1, number;
public static int x=1;
FirstThread(int number){
this.number=number;
System.out.println("create thread"+number);
}
public void run(){
// x=x+1;
while(true) {
// System.out.println("create thread"+x);
System.out.println("線程 "+number+":計(jì)數(shù) "+count);
if(++count==6)return;
}
}
public static void main(String[] args){
for(int i = 0;i< 5; i++) new FirstThread(i+1).start();
}
}
輸出:(每次輸出不同,可見(jiàn)先建立的線程并不是先執(zhí)行,比較混亂)int count= 1, number;
public static int x=1;
FirstThread(int number){
this.number=number;
System.out.println("create thread"+number);
}
public void run(){
// x=x+1;
while(true) {
// System.out.println("create thread"+x);
System.out.println("線程 "+number+":計(jì)數(shù) "+count);
if(++count==6)return;
}
}
public static void main(String[] args){
for(int i = 0;i< 5; i++) new FirstThread(i+1).start();
}
}
create thread1
create thread2
create thread3
線程 1:計(jì)數(shù) 1
線程 1:計(jì)數(shù) 2
create thread4
線程 1:計(jì)數(shù) 3
線程 2:計(jì)數(shù) 1
線程 1:計(jì)數(shù) 4
線程 2:計(jì)數(shù) 2
線程 2:計(jì)數(shù) 3
線程 2:計(jì)數(shù) 4
線程 2:計(jì)數(shù) 5
線程 3:計(jì)數(shù) 1
線程 3:計(jì)數(shù) 2
線程 3:計(jì)數(shù) 3
create thread5
線程 3:計(jì)數(shù) 4
線程 4:計(jì)數(shù) 1
線程 4:計(jì)數(shù) 2
線程 4:計(jì)數(shù) 3
線程 4:計(jì)數(shù) 4
線程 4:計(jì)數(shù) 5
線程 3:計(jì)數(shù) 5
線程 1:計(jì)數(shù) 5
線程 5:計(jì)數(shù) 1
線程 5:計(jì)數(shù) 2
線程 5:計(jì)數(shù) 3
線程 5:計(jì)數(shù) 4
線程 5:計(jì)數(shù) 5
Runnable實(shí)例化代碼
如果類繼承了別的類,就不能繼承 Thread 了,就要實(shí)現(xiàn) Runnable 接口了
public class FirstRunnale implements Runnable{
int number,count;
FirstRunnale(int number){
this.number=number;
System.out.println("create thread"+number);
}
public void run(){
while(true) {
// System.out.println("create thread"+x);
System.out.println("線程 "+number+":計(jì)數(shù) "+count);
if(++count==6)return;
}
}
public static void main(String[] args){
for(int i=0;i<5;i++){
new Thread(new FirstRunnale(i+1)).start();
}
}
}
三、啟動(dòng)線程 int number,count;
FirstRunnale(int number){
this.number=number;
System.out.println("create thread"+number);
}
public void run(){
while(true) {
// System.out.println("create thread"+x);
System.out.println("線程 "+number+":計(jì)數(shù) "+count);
if(++count==6)return;
}
}
public static void main(String[] args){
for(int i=0;i<5;i++){
new Thread(new FirstRunnale(i+1)).start();
}
}
}
在線程的Thread對(duì)象上調(diào)用start()方法,而不是run()或者別的方法。
在調(diào)用start()方法之前:線程處于新?tīng)顟B(tài)中,新?tīng)顟B(tài)指有一個(gè)Thread對(duì)象,但還沒(méi)有一個(gè)真正的線程。
在調(diào)用start()方法之后:發(fā)生了一系列復(fù)雜的事情
啟動(dòng)新的執(zhí)行線程(具有新的調(diào)用棧);
該線程從新?tīng)顟B(tài)轉(zhuǎn)移到可運(yùn)行狀態(tài);
當(dāng)該線程獲得機(jī)會(huì)執(zhí)行時(shí),其目標(biāo)run()方法將運(yùn)行。
注意:對(duì)Java來(lái)說(shuō),run()方法沒(méi)有任何特別之處。像main()方法一樣,它只是新線程知道調(diào)用的方法名稱(和簽名)。因此,在Runnable上或者Thread上調(diào)用run方法是合法的。但并不啟動(dòng)新的線程。
四、補(bǔ)充說(shuō)明
1、線程的名字,一個(gè)運(yùn)行中的線程總是有名字的,名字有兩個(gè)來(lái)源,一個(gè)是虛擬機(jī)自己給的名字,
一個(gè)是你自己的定的名字。在沒(méi)有指定線程名字的情況下,虛擬機(jī)總會(huì)為線程指定名字,并且主線
程的名字總是mian,非主線程的名字不確定。
2、線程都可以設(shè)置名字,也可以獲取線程的名字,連主線程也不例外。
3、獲取當(dāng)前線程的對(duì)象的方法是:Thread.currentThread();
4、在上面的代碼中,只能保證:每個(gè)線程都將啟動(dòng),每個(gè)線程都將運(yùn)行直到完成。一系列線程以某
種順序啟動(dòng)并不意味著將按該順序執(zhí)行。對(duì)于任何一組啟動(dòng)的線程來(lái)說(shuō),調(diào)度程序不能保證其執(zhí)行
次序,持續(xù)時(shí)間也無(wú)法保證。
5、當(dāng)線程目標(biāo)run()方法結(jié)束時(shí)該線程完成。
6、一旦線程啟動(dòng),它就永遠(yuǎn)不能再重新啟動(dòng)。只有一個(gè)新的線程可以被啟動(dòng),并且只能一次。一個(gè)
可運(yùn)行的線程或死線程可以被重新啟動(dòng)。
7、線程的調(diào)度是JVM的一部分,在一個(gè)CPU的機(jī)器上上,實(shí)際上一次只能運(yùn)行一個(gè)線程。一次只有一
個(gè)線程棧執(zhí)行。JVM線程調(diào)度程序決定實(shí)際運(yùn)行哪個(gè)處于可運(yùn)行狀態(tài)的線程。
眾多可運(yùn)行線程中的某一個(gè)會(huì)被選中做為當(dāng)前線程??蛇\(yùn)行線程被選擇運(yùn)行的順序是沒(méi)有保障的。
8、盡管通常采用隊(duì)列形式,但這是沒(méi)有保障的。隊(duì)列形式是指當(dāng)一個(gè)線程完成“一輪”時(shí),它移到
可運(yùn)行隊(duì)列的尾部等待,直到它最終排隊(duì)到該隊(duì)列的前端為止,它才能被再次選中。事實(shí)上,我們
把它稱為可運(yùn)行池而不是一個(gè)可運(yùn)行隊(duì)列,目的是幫助認(rèn)識(shí)線程并不都是以某種有保障的順序排列
唱呢個(gè)一個(gè)隊(duì)列的事實(shí)。
9、盡管我們沒(méi)有無(wú)法控制線程調(diào)度程序,但可以通過(guò)別的方式來(lái)影響線程調(diào)度的方式。
posted on 2009-02-26 19:26 草原上的駱駝 閱讀(487) 評(píng)論(0) 編輯 收藏 所屬分類: JAVA基礎(chǔ)知識(shí)