上一篇我們提到到底該如何選擇多線程使用哪一個?
我們通過一個例子來說明他們的不同:
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
今天就先介紹到這裏,後面我們在探討線程.