Thread和Runnable你該選哪個
一般使用中,很多有經驗的老程式設計師大部分都是不約而同的使用Runnable多一些,為什麼呢,我也問過公司的那些老員工,他們也說不出個所以然,只是使用經驗讓他們去這樣選擇,這裡我去檢視Thread和Runnable的原始碼,發覺Thread內部也是實現的Runnable的介面的,慢慢的好像有些頭緒,Thread類片段原始碼如下:
Java程式碼- /**
- * If this thread was constructed using a separate
- * <code>Runnable</code> run object, then that
- * <code>Runnable</code> object's <code>run</code> method is called;
- * otherwise, this method does nothing and returns.
- * <p>
- * Subclasses of <code>Thread</code> should override this method.
- *
- * @see #start()
- * @see #stop()
- * @see #Thread(ThreadGroup, Runnable, String)
- */
- publicvoid run() {
- if (target != null) {
- target.run();
- }
- }
這裡寫到如果target不為空的話,則呼叫它的run方法,這個target,則是Runnable的例項物件,也就是說,繼承於Thread並實現它的run方法能建立一個執行緒,實際這個run方法就是Runnable所提供的代理物件所有的,因此我們得到Runnable的優點之後,再拿過來跟Thread的優先一一對比,也就大體能知道,使用時,到底選用Thread好還是Runnable好點。
經對比,Runnable的優勢有以下幾點:1.適合多個相同程式程式碼的執行緒去處理同一個資源(多執行緒內的資料共享) 2.避免java特性中的單根繼承限制 3.增加程式健壯性,資料被共享時,仍然可以保持程式碼和資料的分離和獨立 4.更能體現java面向物件的設計特點
針對以上的特點2,3,4我們大體可以理解,而對於優勢1可能不太深刻,這邊,為了體現它在多執行緒內的資料共享方面的優勢,我們用張孝祥所舉的經典的買票例子來演示下,多個視窗同時賣票,這裡多個視窗即多個執行緒,所賣的票則是需要共享的資料。
以下是Thread的實現方式:
Java程式碼- class hello extends Thread {
- publicvoid run() {
- for (int i = 0; i < 7; i++) {
- if (count > 0) {
- System.out.println("count= " + count--);
- }
- }
- }
- publicstaticvoid main(String[] args) {
- hello h1 = new hello();
- hello h2 = new hello();
- hello h3 = new hello();
- h1.start();
- h2.start();
- h3.start();
- }
- privateint count = 5;
- }
執行結果為:
Java程式碼- count= 5
- count= 4
- count= 3
- count= 2
- count= 1
- count= 5
- count= 4
- count= 3
- count= 2
- count= 1
- count= 5
- count= 4
- count= 3
- count= 2
- count= 1
以上結果顯示,假使這真是一個買票系統count為總車票數的話,以上程式碼並未實現執行緒內的資料共享
下面我們看下Runnable的實現,程式碼如下:
Java程式碼- class MyThread implements Runnable{
- privateint ticket = 5; //5張票
- publicvoid run() {
- for (int i=0; i<=20; i++) {
- if (this.ticket > 0) {
- System.out.println(Thread.currentThread().getName()+ "正在賣票"+this.ticket--);
- }
- }
- }
- }
- publicclass lzwCode {
- publicstaticvoid main(String [] args) {
- MyThread my = new MyThread();
- new Thread(my, "1號視窗").start();
- new Thread(my, "2號視窗").start();
- new Thread(my, "3號視窗").start();
- }
- }
執行結果為:
Java程式碼- count= 5
- count= 4
- count= 3
- count= 2
- count= 1