Java學習之線程回顧與總結__java學習

來源:互聯網
上載者:User

Java提供了線程類Thread來建立多線程的程式。其實,建立線程與建立普通的類的對象的操作是一樣的,而線程就是Thread類或其子類的執行個體對象。每個Thread對象描述了一個單獨的線程。要產生一個線程,有兩種方法:

◆需要從Java.lang.Thread類派生一個新的線程類,重寫它的run()方法。 
◆實現Runnalbe介面,重載Runnalbe介面中的run()方法。

具體步驟分別如下:
一、通過擴充(繼承)Thread類來建立多線程
1,定義一個繼承於Thread的類,並重寫run()方法;
2,建立該Thread子類的執行個體,即建立線程對象;
3,調用該線程對象的start()方法啟動該線程。
例:

class MyThread extends Thread {// 1,定義Thread類的子類,public void run() {// 並重寫Thread類的run()方法。System.out.println(this.getName());}}public class TestThread {public static void main(String args[]) {System.out.println(Thread.currentThread().getName());// currentThread()方法是Thread類的靜態方法,該方法總是返回當前正在執行的線程對象的引用。// getName()方法是Thread類的執行個體方法,該方法返回調用該方法的線程的名字。MyThread thread1 = new MyThread();// 2,建立Thread類的子類的執行個體,即建立線程對象。MyThread thread2 = new MyThread();thread1.start();// 3,<span style="color: rgb(51, 51, 51); font-family: verdana, Arial, Helvetica, sans-serif; font-size: 16px; line-height: 28px; ">調用該線程對象的start()方法啟動該線程</span>。thread2.start();}}

二、通過實現Runnable介面來建立多線程
1,定義一個實現了Runnable介面的類,並實現run()方法;
2,建立一個該類的對象(Runnable對象);
3,建立一個Thread類的對象並傳入Runnable對象;
4,調用該Thread類對象的start()方法啟動該線程。
例:

class MyRunnable implements Runnable {// 1,定義一個實現了Runnable介面的類public void run() {// 2,實現run()方法System.out.println(Thread.currentThread().getName());} }public class TestRunnable {public static void main(String args[]) {MyRunnable r1 = new MyRunnable();// 3,建立Runnable類的對象MyRunnable r2 = new MyRunnable();MyRunnable r3 = new MyRunnable();Thread thread1 = new Thread(r1, "MyThread1");// 4,建立Thread類對象並傳入Runnable類對象Thread thread2 = new Thread(r2);thread2.setName("MyThread2");Thread thread3 = new Thread(r3);thread1.start();// 5,調用Thread類對象的start()方法thread2.start();thread3.start();}}

為什麼Java要提供兩種方法來建立線程呢。它們都有哪些區別。相比而言,哪一種方法更好呢。

在Java中,類僅支援單繼承,也就是說,當定義一個新的類的時候,它只能擴充一個外部類.這樣,如果建立自訂線程類的時候是通過擴充 Thread類的方法來實現的,那麼這個自訂類就不能再去擴充其他的類,也就無法實現更加複雜的功能。因此,如果自訂類必須擴充其他的類,那麼就可以使用實現Runnable介面的方法來定義該類為線程類,這樣就可以避免Java單繼承所帶來的局限性。

還有一點最重要的就是使用實現Runnable介面的方式建立的線程可以處理同一資源,從而實現資源的共用。 關於具體使用
(1)通過擴充Thread類來建立多線程
假設一個影院有三個售票口,分別用於向兒童、成人和老人售票。影院為每個視窗放有100張電影票,分別是兒童票、成人票和老人票。三個視窗需要同時賣票,而現在只有一個售票員,這個售票員就相當於一個CPU,三個視窗就相當於三個線程。通過程式來看一看是如何建立這三個線程的。

public class MutliThreadDemo {    public static void main(String [] args){        MutliThread m1=new MutliThread("Window 1");        MutliThread m2=new MutliThread("Window 2");        MutliThread m3=new MutliThread("Window 3");        m1.start();        m2.start();        m3.start();    }}class MutliThread extends Thread{    private int ticket=100;//每個線程都擁有100張票    MutliThread(String name){        super(name);//調用父類帶參數的構造方法    }    public void run(){        while(ticket>0){            System.out.println(ticket--+" is saled by "+Thread.currentThread().getName());        }    }}

程式中定義一個線程類,它擴充了Thread類。利用擴充的線程類在MutliThreadDemo類的主方法中建立了三個線程對象,並通過start()方法分別將它們啟動。
從結果可以看到,每個線程分別對應100張電影票,之間並無任何關係,這就說明每個線程之間是平等的,沒有優先順序關係,因此都有機會得到CPU的處理。但是結果顯示這三個線程並不是依次交替執行,而是在三個線程同時被執行的情況下,有的線程被分配時間片的機會多,票被提前賣完,而有的線程被分配時間片的機會比較少,票遲一些賣完。
可見,利用擴充Thread類建立的多個線程,雖然執行的是相同的代碼,但彼此相互獨立,且各自擁有自己的資源,互不干擾。 (2)通過實現Runnable介面來建立多線程

public class MutliThreadDemo2 {    public static void main(String [] args){        MutliThread m1=new MutliThread("Window 1");        MutliThread m2=new MutliThread("Window 2");        MutliThread m3=new MutliThread("Window 3");        Thread t1=new Thread(m1);        Thread t2=new Thread(m2);        Thread t3=new Thread(m3);        t1.start();        t2.start();        t3.start();    }}class MutliThread implements Runnable{    private int ticket=100;//每個線程都擁有100張票    private String name;    MutliThread(String name){        this.name=name;    }    public void run(){        while(ticket>0){            System.out.println(ticket--+" is saled by "+name);        }    }}

由於這三個線程也是彼此獨立,各自擁有自己的資源,即100張電影票,因此程式輸出的結果和(1)結果大同小異。均是各自線程對自己的100張票進行單獨的處理,互不影響。
可見,只要現實的情況要求保證建立線程彼此相互獨立,各自擁有資源,且互不干擾,採用哪個方式來建立多線程都是可以的。因為這兩種方式建立的多線程程式能夠實現相同的功能。

(3)通過實現Runnable介面來實現線程間的資源共用
現實中也存在這樣的情況,比如類比一個火車站的售票系統,假如當日從A地發往B地的火車票只有100張,且允許所有視窗賣這100張票,那麼每一個視窗也相當於一個線程,但是這時和前面的例子不同之處就在於所有線程處理的資源是同一個資源,即100張車票。如果還用前面的方式來建立線程顯然是無法實現的,這種情況該怎樣處理呢。看下面這個程式,程式碼如下所示:

public class MutliThreadDemo3 {    public static void main(String [] args){        MutliThread m=new MutliThread();        Thread t1=new Thread(m,"Window 1");        Thread t2=new Thread(m,"Window 2");        Thread t3=new Thread(m,"Window 3");        t1.start();        t2.start();        t3.start();    }}class MutliThread implements Runnable{    private int ticket=100;//每個線程都擁有100張票    public void run(){        while(ticket>0){            System.out.println(ticket--+" is saled by "+Thread.currentThread().getName());        }    }}

結果正如前面分析的那樣,程式在記憶體中僅建立了一個資源,而建立的三個線程都是基於訪問這同一資源的,並且由於每個線程上所啟動並執行是相同的代碼,因此它們執行的功能也是相同的。
可見,如果現實問題中要求必須建立多個線程來執行同一任務,而且這多個線程之間還將共用同一個資源,那麼就可以使用實現Runnable介面的方式來建立多線程程式。而這一功能通過擴充Thread類是無法實現的。
實現Runnable介面相對於擴充Thread類來說,具有無可比擬的優勢。這種方式不僅有利於程式的健壯性,使代碼能夠被多個線程共用,而且代碼和資料資源相對獨立,從而特別適合多個具有相同代碼的線程去處理同一資源的情況。這樣一來,線程、代碼和資料資源三者有效分離,很好地體現了物件導向程式設計的思想。因此,幾乎所有的多線程程式都是通過實現Runnable介面的方式來完成的。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.