Java多線程基礎

Java實現多線程所有方法都要通過Tread類實現,Thread類中的Start0()方法使用JNI(Java Native Interface)來和操作系統交互,進行線程計算。

有三種方法實現Java多線程編程:

  1. 繼承Thread類,在子類中重寫Thread類的run()方法。
  2. 實現Runnable接口,在實現接口的類中實現方法run()。
  3. 用類A實現callable接口,再用A的對象初始化一個FutureTask對象B,FutureTask實現的是RunnalbleTask接口,RunnalbleTask繼承了Runnalble接口以及的Future類,因此可以用對象B初始化一個Thread對象。

第一種:繼承Thread類
Thread類中有run()方法,run()中爲多線程中的資源代碼,也就是線程中要執行的代碼(此時先不管run()方法重寫前是是什麼內容)。
Thread類中的start()方法中調用了start0()方法,這個方法是在Thread類被創建的時候,在靜態塊中使用registerNatives()創建的本地方法。在本地方法start0()中最終會實現run()方法中的代碼,實現本地線程運行run()中的代碼。
Thread方法被創建時,通過registerNatives()創建了一系列本地方法,其中就包括start0()

demo代碼爲:

import java.lang.Thread;

public class ThreadsDemo extends Thread {

    String title="";

    ThreadsDemo(String title){
        this.title=title;
    }

    @Override
    public  void run(){
        for(int i=0;i<10;i++) {
            System.out.print(this.title);
        }
    }

    public static void main(String[] args){
        ThreadsDemo threadA = new ThreadsDemo("a");
        ThreadsDemo threadB = new ThreadsDemo("b");
        ThreadsDemo threadC = new ThreadsDemo("c");
        threadA.start();
        threadB.start();
        threadC.start();
    }
}

第二種:實現Runnable接口
我們知道在第一種方法中通過重寫Thread的run()方法來寫入我們的業務代碼,其實Thread中run()方法本來實現的是一個Runnable接口實現類中的run()方法。Thread的構造函數中可以使用Runnable接口的實現類初始化。因此我們可以使用Runnable實現類來初始化Thread對象。然後再使用Thread中的start()啓動線程,後續動作就和上面的一樣了。

優點:相比第一種,實現Runnable接口可以避免受困於多繼承的侷限。

在這裏插入圖片描述
在這裏插入圖片描述

import java.lang.Runnable;

public class RunnableDemo implements Runnable{

    public int a = 0;

    public synchronized  void run(){
        for(int i=0;i<100000000;i++) {
            this.a = a + 1;
            //System.out.println(a);
        }
        System.out.println(a);
    }


    public static void main(String[] args) throws Exception{


        RunnableDemo rd = new RunnableDemo();

        Thread ta = new Thread(rd);
        Thread tb = new Thread(rd);

        ta.setPriority(10);
        ta.start();
        //ta.join();


        tb.start();
        //tb.join();

        System.out.println("wed"+rd.a);
    }
}

第三種:實現callable接口

callable接口中的call方法可以有返回值。使用FutureTask的get方法獲取。

Callable接口所在的包爲JUC(java.util.concurrent),實現Callable同樣最終要通過Thread類實現多線程。

callable對象作爲參數 初始化FutureTask類,FutureTask類實現了RunnableFuture接口,
RunnableFuture接口繼承了Runnable和Future接口,其中繼承Runnable可以使RunnableFuture接口可以像Runnable一樣初始化Thread類,Future接口提供了get方法,用來獲取Callable中call()方法的返回值。

import java.util.concurrent.Callable;
import java.lang.String;
import java.util.concurrent.FutureTask;

public class CallableDemo implements Callable<Integer> {

    public Integer call() throws Exception{
        int re=0;
        for(int i=0;i<10;i++){
            System.out.println(i);
            re++;
        }
        return re;
    }

    public static void main(String[] args) throws Exception{
        CallableDemo cd = new CallableDemo();
        FutureTask<Integer> ft = new FutureTask(cd);
        Thread ta = new Thread(ft);
        ta.start();
        int a = ft.get();
        System.out.println(a);

    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章