Java:多執行緒 - 建立方法
多執行緒的理解
可以理解成程序中獨立執行的子任務,比如QQ.exe執行時的視訊聊天執行緒,下載檔案執行緒,傳送表情執行緒等,這些不同的任務或功能可以“同時”執行。實際上,CPU在這些執行緒之間不斷的切換,這樣做可以最大限度的利用CPU的空閒時間。
Java多執行緒的建立和使用
java中的main是一個獨立的執行緒,對於多執行緒,我們主要使用三種方法建立和使用:
- 繼承Thread類,重寫run(),例項化並使用
- 實現Runnable介面,重寫run(),作為Thread的Target,例項化並使用
- 實現Callable介面,FutureTask包裝類作為Thread的Target,例項化並使用
1)繼承Thread類,重寫run()方法
寫一個最簡單的例子實現多執行緒,建立class MyThread繼承Thread類,並且
重寫run(),方法體輸出文字。
在main中例項化並呼叫start()進入RUNNABLE狀態聽候CPU呼叫run(),
此時即實現了多執行緒!
public class B{
public static void main(String[] args){
MyThread mtd = new MyThread();
mtd.start();
System.out.println("operation done" );
}
}
class MyThread extends Thread{
@Override
public void run(){
System.out.println("MyThread");
}
}
輸出:
operation done
MyThread
or
MyThread
operation done
上述程式碼每次執行結果不一定相同,也說明了多執行緒之間的任務完成次序並不像
單執行緒多個任務那樣線性。
2) 實現Runnable,重寫run(),作為Thread的target成員變數
接下來看Runnable,這裡呼叫的是Thread(Runnable target)這個構造器,
等同於呼叫Thread(null,target,gname),gname代表預設自動生成的執行緒名“Thread-”+n,當構造引數target不為null時,該Thread執行時執行target.run(),否則將不做任何事。
public class B{
public static void main(String[] args){
MyRunnable myRunnable = new MyRunnable();
Thread myThread = new Thread(myRunnable);
myThread.start();
}
}
class MyRunnable implements Runnable{
@Override
public void run(){
System.out.println("My Runnable thread running");
}
}
輸出:
My Runnable thread running
給建立的Thread取名
利用Thread類中 Thread(“String name”) 構造法可以覆蓋預設的其預設方法中的“Thread-”+n
相當於呼叫 Thread(null,null,name)
public class B{
public static void main(String[] args){
MyRunnable myRunnable = new MyRunnable();
Thread myThread1 = new MyThread("Thread Dark");
Thread myThread2 = new MyThread(myRunnable,"Thread Light");
myThread1.start();
myThread2.start();
}
}
class MyThread extends Thread{
public MyThread(Runnable myRunnable,String name){
super(myRunnable,name);
}
public MyThread(String name){
super(name);
}
@Override
public void run(){
super.run();
System.out.println("my subthread running "+ Thread.currentThread().getName());
}
}
class MyRunnable implements Runnable{
@Override
public void run(){
System.out.println("runnable thread running"+Thread.currentThread().getName());
}
}
輸出
runnable thread runningThread Light
my subthread running Thread Light
my subthread running Thread Dark
這裡看到Thread Light呼叫了Runnable實現類MyRunnable中的run()方法,
Thread Dark由於target = null,所以super.run()將不執行執行緒任何任務。
3)實現Callable介面,用FutureTask類包裝,作為Thread target成員例項化執行緒
Interface Callable<T>
是一個T call() throws Exception
功能介面,功能類似Runnable,但是call()比run()多了返回型別T和丟擲異常的規則設定。
Class FutureTask<T>
是一個實現了RunnableFuture<T>
的類,成員變數有Callable callable,Runnable runnable,和T result
主要有public FutureTask(Callable<T> callable)
和public FutureTask(Runnable runnable,T result)
兩種構造法。
import java.math.*;
import java.util.*;
import java.util.concurrent.*;
public class B{
public static void main(String[] args){
MyCallable myCallable = new MyCallable();
FutureTask<Integer> ft = new FutureTask<Integer>(myCallable);
Thread myThread3 = new Thread(ft,"Thread Future");
myThread3.start();
try{
int sum = ft.get();
System.out.println("1+2+3+...+10= " + sum);
}catch(Exception e){
e.printStackTrace();
}
}
}
class MyCallable implements Callable<Integer>{
private int i = 0;
@Override
public Integer call(){
int sum = 0;
System.out.println("callable thread running: "+Thread.currentThread().getName());
while (i<11){
sum+=i++;
}
return sum;
}
}
輸出結果
callable thread running: Thread Future
1+2+3+...+10= 55