多線程創建方式四種


1、繼承Thread類創建多線程:繼承java.lang.Thread類,重寫Thread類的run()方法,在run()方法中實現運行在線程上的代碼,調用start()方法開啟線程。

  Thread 類本質上是實現了 Runnable 接口的一個實例,代表一個線程的實例。啟動線程的唯一方法就是通過 Thread 類的 start()實例方法。start()方法是一個 native 方法,它將啟動一個新線程,並執行 run()方法。

public class MyThread extends Thread {
  public void run() {
    System.out.println("MyThread.run()");
  }
}
MyThread myThread1 = new MyThread();
myThread1.start();

 

2、實現Runable接口:實現java.lang.Runnable接口,重寫run()方法,在run()方法中實現運行在線程上的代碼。

  如果自己的類已經 extends 另一個類,就無法直接 extends Thread,此時,可以實現一個Runnable 接口。

public class MyThread extends OtherClass implements Runnable {
    public void run() {
        System.out.println("MyThread.run()");
    }
}  
//啟動 MyThread,需要首先實例化一個 Thread,並傳入自己的 MyThread 實例:
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
//事實上,當傳入一個 Runnable target 參數給 Thread 后,Thread 的 run()方法就會調用
target.run()
public void run() {
  if (target != null) {
  target.run();
  }
}

補充:兩種多線程方式比較:這兩種顯示的創建線程的方式,我們在實際編程中都不用,要用線程池進行統一的資源管理。

(1)Runable方法將線程同程序代碼、數據有效的分離,代碼相對整潔。

(2)避免java單繼承的局限性。一個已經繼承了某一個類的子類去創建線程,由於java子類不能繼承兩個父類,因此不能用Thread的方式,要使用實現Runnable接口的方式。

 

3、使用ExecutorService 、Callable<Class> 、Future 創建有返回值的線程

  有返回值的任務必須實現 Callable 接口,類似的,無返回值的任務必須實現 Runnable 接口。執行Callable 任務后,可以獲取一個 Future 的對象,在該對象上調用 get 就可以獲取到 Callable 任務返回的 Object 了,再結合線程池接口 ExecutorService 就可以實現傳說中有返回結果的多線程了。

//創建一個線程池
ExecutorService pool = Executors.newFixedThreadPool(taskSize);
// 創建多個有返回值的任務
List<Future> list = new ArrayList<Future>();
for (int i = 0; i < taskSize; i++) {
  Callable c = new MyCallable(i + " ");
  // 執行任務並獲取 Future 對象
  Future f = pool.submit(c);
  list.add(f);
}
// 關閉線程池
pool.shutdown();
// 獲取所有並發任務的運行結果
for (Future f : list) {
  // 從 Future 對象上獲取任務的返回值,並輸出到控制台
  System.out.println("res:" + f.get().toString());
}

 

4、基於線程池的方式

  線程和數據庫連接這些資源都是非常寶貴的資源。那么每次需要的時候創建,不需要的時候銷毀,是非常浪費資源的。那么我們就可以使用緩存的策略,也就是使用線程池。

// 創建線程池
ExecutorService threadPool = Executors.newFixedThreadPool(10);
while(true) {
    threadPool.execute(new Runnable() { // 提交多個線程任務,並執行
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " is running ..");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM