多線程進程該選擇哪一個

上一篇我們提到到底該如何選擇多線程使用哪一個?

我們通過一個例子來說明他們的不同:

Thread 代碼如下:

package com.game.test;

public class TicketThread extends Thread{

    private int ticketCount=5;
    
    public void run(){
        for(int i=0;i<7;i++){
            if(this.ticketCount>0){
                System.out.println("剩餘的數量====>"+ticketCount--);
            }
            
        }
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //模擬3個線程取票
        TicketThread t1=new TicketThread();
        TicketThread t2=new TicketThread();
        TicketThread t3=new TicketThread();
        
        t1.start();
        t2.start();
        t3.start();
    }

}

[輸出結果]


剩餘的數量====>5
剩餘的數量====>4
剩餘的數量====>3
剩餘的數量====>2
剩餘的數量====>1
剩餘的數量====>5
剩餘的數量====>4
剩餘的數量====>5
剩餘的數量====>4
剩餘的數量====>3
剩餘的數量====>3
剩餘的數量====>2
剩餘的數量====>1
剩餘的數量====>2
剩餘的數量====>1


如果這個是一個買票系統的話, 如果ticket是車票數量的話,說明並沒有實現資源共享.

我們換爲runnable 代碼如下:


package com.game.test;

public class TicketRunnable implements Runnable{

    private int ticket=5;
    
    /**
     * @param args
     */
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<20;i++){
            if(this.ticket>0){
            System.out.println("當前線程"+Thread.currentThread().getName()+"正在賣票"+ticket--);
        
            }
        }
    }
    public static void main(String[] args) {
        TicketRunnable tr=new TicketRunnable();
        new Thread(tr,"1號窗臺").start();
        new Thread(tr,"2號窗臺").start();
        new Thread(tr,"3號窗臺").start();
    }
}


當前線程2號窗臺正在賣票4
當前線程2號窗臺正在賣票2
當前線程2號窗臺正在賣票1
當前線程3號窗臺正在賣票3
當前線程1號窗臺正在賣票5

總結一下吧:

實現Runnable接口比繼承Thread類所具有的優勢:

1):適合多個相同的程序代碼的線程去處理同一個資源

2):可以避免java中的單繼承的限制

3):增加程序的健壯性,代碼可以被多個線程共享,代碼和數據獨立。


所以換是建議大家實現接口的方式操作線程.

另外如果沒有指定線程的名字的話,系統會自動提供名字 例如:

package com.game.test;

public class GetThreadName implements Runnable{
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        GetThreadName gr=new GetThreadName();
        new Thread(gr,"A").start();
        new Thread(gr,"B").start();
        new Thread(gr).start();
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<3;i++){
            System.out.println(Thread.currentThread().getName());
        }
    }

}

[輸出結果]
B
B
B
Thread-0
Thread-0
Thread-0
A
A
A

其實我們的main方法也是一個線程.在java中所有的線程都是同時啓動的,至於什麼時候,哪個先執行,完全看誰先得到系統的CPU資源.

在java中,我們每次程序運行至少啓動2個線程.一個是main線程,一個是垃圾收集線程.

如何判斷線程是否已經啓動呢?

package com.game.test;

public class GetThreadName implements Runnable{
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        GetThreadName gr=new GetThreadName();
        Thread t1=new Thread(gr);
        System.out.println("線程啓動之前========>"+t1.isAlive());
        t1.start();
        System.out.println("線程啓動之後========>"+t1.isAlive());
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<3;i++){
            System.out.println(Thread.currentThread().getName());
        }
    }

}

[結果如下]

線程啓動之前========>false
線程啓動之後========>true
Thread-0
Thread-0
Thread-0


今天就先介紹到這裏,後面我們在探討線程.






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章