多執行緒第二旅
2.3 Thread與Runnable區別
首先從使用形式來講,明顯使用Runnable實現多執行緒要比繼承Thread類要好,因為可以避免單繼承侷限。
除了這點以外,Thread和Runnable還有什麼區別呢?
來看Thread類的定義:
Public class Thread implements Runnable
可見:Thread類是Runnable介面的子類,那麼Thread類一定覆寫了Runnable介面的run()方法
在多執行緒的處理上使用的就是代理設計模式。除了以上的關係之外,實際上在開發之中使用Runnable還有一個特
點:使用Runnable實現的多執行緒的程式類可以更好的描述出程式共享的概念(並不是說Thread不能)
使用Thread實現資料共享(產生若干執行緒進行同一資料的處理操作:
上程式碼:
class MyThread extends Thread {
private int ticket = 10 ; // 一共10張票
@Override
public void run() {
while(this.ticket>0){
System.out.println("剩餘票數:"+this.ticket -- );
}
}}
public class Test {
public static void main(String[] args) {
new MyThread().start();
new MyThread().start();
new MyThread().start();
}
}
此時啟動三個執行緒實現賣票處理。結果變為了賣各自的票。
使用Runnable實現共享
上程式碼:
class MyThread implements Runnable {
private int ticket = 10 ; // 一共10張票
@Override
public void run() {
while(this.ticket>0){
System.out.println("剩餘票數:"+this.ticket -- );
}
}
}
public class Test{
public static void main(String[] args) {
MyThread mt = new MyThread() ;//只建立一個物件
new Thread(mt).start();
new Thread(mt).start();//啟動兩個執行緒
}
}
Runnable實現的多執行緒的程式類可以更好的描述出程式共享的概念
2.4實現Callable<v>實現多執行緒(juc)--當執行緒有返回值時只能實現Callable實現多執行緒
這是JDK1.5新增的併發程式程式設計包
java.uti.concurrent.Callable<v>
2.4.1實現Callable介面而後覆寫call()方法,有返回值:
V call() throws exception;
2.4.2Future<V>介面:
V get() throws InterruptedException,ExecutionException;
就可以取得Callable介面的返回值
見程式碼:
package www.bit.java;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class MyThread implements Callable<String> {
private int ticket = 10 ; // 一共10張票
@Override//準確覆寫,方法名,返回值,許可權,如果不一樣,都會報錯
public String call() throws Exception {//覆寫call方法
while(this.ticket>0){
System.out.println("剩餘票數:"+this.ticket -- );
}
return "票賣完了,下次吧。。。" ;
}
}
public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread();
FutureTask<String> futureTask = new FutureTask<>(myThread);
Thread thread = new Thread(futureTask);//兩個執行緒
Thread thread1 = new Thread(futureTask);
thread.start();
thread1.start();
//出現get異常,用ctrl+alt+t
try {
System.out.println(futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
}
}
}