Java中線(xiàn)程的創(chuàng)建有兩種方式:
1.通過(guò)繼承Thread類(lèi)楣号,重寫(xiě)Thread的run()方法丙唧,將線(xiàn)程運(yùn)行的邏輯放在其中
2.通過(guò)實(shí)現(xiàn)Runnable接口欢际,實(shí)例化Thread類(lèi)
在實(shí)際應(yīng)用中澜沟,我們經(jīng)常用到多線(xiàn)程丐箩,如車(chē)站的售票系統(tǒng)撬槽,車(chē)站的各個(gè)售票口相當(dāng)于各個(gè)線(xiàn)程此改。當(dāng)我們做這個(gè)系統(tǒng)的時(shí)候可能會(huì)想到兩種方式來(lái)實(shí)現(xiàn),繼承Thread類(lèi)或?qū)崿F(xiàn)Runnable接口侄柔,現(xiàn)在看一下這兩種方式實(shí)現(xiàn)的兩種結(jié)果共啃。
Java代碼:
package com.threadtest;
class MyThread extends Thread{
???? privateintticket?=10;
???? privateString?name;
public? MyThread(String?name){
???? this.name?=name;
}
public? void? run(){
??????????? for(inti?=0;i<500;i++){
???????????????????? if (this.ticket>0){
?????????????????????????????? System.out.println(this.name+"賣(mài)票---->"+(this.ticket--));
????????????????????? }
??????????????? }
? }
?}
public class ThreadDemo?{
public static void main(String[]?args)?{
?????? MyThread?mt1=newMyThread("一號(hào)窗口");
?????? MyThread?mt2=newMyThread("二號(hào)窗口");
?????? MyThread?mt3=newMyThread("三號(hào)窗口");
?????? mt1.start();
?????? mt2.start();
??????? mt3.start();
}
}
運(yùn)行結(jié)果如下:
一號(hào)窗口賣(mài)票---->10
一號(hào)窗口賣(mài)票---->9
二號(hào)窗口賣(mài)票---->10
一號(hào)窗口賣(mài)票---->8
一號(hào)窗口賣(mài)票---->7
一號(hào)窗口賣(mài)票---->6
三號(hào)窗口賣(mài)票---->10
一號(hào)窗口賣(mài)票---->5
一號(hào)窗口賣(mài)票---->4
一號(hào)窗口賣(mài)票---->3
一號(hào)窗口賣(mài)票---->2
一號(hào)窗口賣(mài)票---->1
二號(hào)窗口賣(mài)票---->9
二號(hào)窗口賣(mài)票---->8
三號(hào)窗口賣(mài)票---->9
三號(hào)窗口賣(mài)票---->8
三號(hào)窗口賣(mài)票---->7
三號(hào)窗口賣(mài)票---->6
三號(hào)窗口賣(mài)票---->5
三號(hào)窗口賣(mài)票---->4
三號(hào)窗口賣(mài)票---->3
三號(hào)窗口賣(mài)票---->2
三號(hào)窗口賣(mài)票---->1
二號(hào)窗口賣(mài)票---->7
二號(hào)窗口賣(mài)票---->6
二號(hào)窗口賣(mài)票---->5
二號(hào)窗口賣(mài)票---->4
二號(hào)窗口賣(mài)票---->3
二號(hào)窗口賣(mài)票---->2
二號(hào)窗口賣(mài)票---->1
通過(guò)實(shí)現(xiàn)Runnable接口的代碼如下:
packagecom.threadtest;
class MyThread1 implements Runnable{
private intticket?=10;
private String?name;
public void run(){
for(inti?=0;i<500;i++){
if(this.ticket>0){
System.out.println(Thread.currentThread().getName()+"賣(mài)票---->"+(this.ticket--));
}
}
}
}
public? class? RunnableDemo?{
public static? void? main(String[]?args)?{
//?TODO?Auto-generated?method?stub
//設(shè)計(jì)三個(gè)線(xiàn)程
MyThread1?mt?=newMyThread1();
Thread?t1?=newThread(mt,"一號(hào)窗口");
Thread?t2?=newThread(mt,"二號(hào)窗口");
Thread?t3?=newThread(mt,"三號(hào)窗口");
//?????????MyThread1?mt2?=?new?MyThread1();
//?????????MyThread1?mt3?=?new?MyThread1();
t1.start();
t2.start();
t3.start();
}
}
運(yùn)行結(jié)果如下:
一號(hào)窗口賣(mài)票---->10
三號(hào)窗口賣(mài)票---->9
三號(hào)窗口賣(mài)票---->7
三號(hào)窗口賣(mài)票---->5
三號(hào)窗口賣(mài)票---->4
三號(hào)窗口賣(mài)票---->3
三號(hào)窗口賣(mài)票---->2
三號(hào)窗口賣(mài)票---->1
一號(hào)窗口賣(mài)票---->8
二號(hào)窗口賣(mài)票---->6
為什么會(huì)出現(xiàn)這種結(jié)果吶。我們不妨做個(gè)比喻暂题,其實(shí)剛的程序移剪,
繼承Thread類(lèi)的,我們相當(dāng)于拿出三件事即三個(gè)賣(mài)票10張的任務(wù)分別分給三個(gè)窗口薪者,他們各做各的事各賣(mài)各的票各完成各的任務(wù)纵苛,因?yàn)镸yThread繼承Thread類(lèi),所以在new MyThread的時(shí)候在創(chuàng)建三個(gè)對(duì)象的同時(shí)創(chuàng)建了三個(gè)線(xiàn)程;
實(shí)現(xiàn)Runnable的赶站,相當(dāng)于是拿出一個(gè)賣(mài)票10張得任務(wù)給三個(gè)人去共同完成幔虏,new MyThread相當(dāng)于創(chuàng)建一個(gè)任務(wù),然后實(shí)例化三個(gè)Thread贝椿,創(chuàng)建三個(gè)線(xiàn)程即安排三個(gè)窗口去執(zhí)行想括。
用圖表示如下:
在我們剛接觸的時(shí)候可能會(huì)迷糊繼承Thread類(lèi)和實(shí)現(xiàn)Runnable接口實(shí)現(xiàn)多線(xiàn)程,其實(shí)在接觸后我們會(huì)發(fā)現(xiàn)這完全是兩個(gè)不同的實(shí)現(xiàn)多線(xiàn)程烙博,一個(gè)是多個(gè)線(xiàn)程分別完成自己的任務(wù)瑟蜈,一個(gè)是多個(gè)線(xiàn)程共同完成一個(gè)任務(wù)。
其實(shí)在實(shí)現(xiàn)一個(gè)任務(wù)用多個(gè)線(xiàn)程來(lái)做也可以用繼承Thread類(lèi)來(lái)實(shí)現(xiàn)只是比較麻煩渣窜,一般我們用實(shí)現(xiàn)Runnable接口來(lái)實(shí)現(xiàn)铺根,簡(jiǎn)潔明了。
大多數(shù)情況下位迂,如果只想重寫(xiě)run()方法掂林,而不重寫(xiě)其他Thread方法泻帮,那么應(yīng)使用Runnable接口。這很重要元莫,因?yàn)槌浅绦騿T打算修改或增強(qiáng)類(lèi)的基本行為,否則不應(yīng)為該類(lèi)(Thread)創(chuàng)建子類(lèi)。
?????????????????????????????????????????????????????????????????????????????????????????????????????????????? ? ? ? ? ? ? ? (轉(zhuǎn)載)