1. 程式人生 > >Java:多執行緒 - 建立方法

Java:多執行緒 - 建立方法

多執行緒的理解

可以理解成程序中獨立執行的子任務,比如QQ.exe執行時的視訊聊天執行緒,下載檔案執行緒,傳送表情執行緒等,這些不同的任務或功能可以“同時”執行。實際上,CPU在這些執行緒之間不斷的切換,這樣做可以最大限度的利用CPU的空閒時間。

Java多執行緒的建立和使用

java中的main是一個獨立的執行緒,對於多執行緒,我們主要使用三種方法建立和使用:

  1. 繼承Thread類,重寫run(),例項化並使用
  2. 實現Runnable介面,重寫run(),作為Thread的Target,例項化並使用
  3. 實現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