帶返回值的線程


  創建一個線程有幾種方式,很容易想到的就是集成Thread類,實現Runnable接口,還有一種方式就是自己定義的線程類實現Callable接口,這種方式相較於實現Runnable接口具有帶有返回值的特點,大家都知道在java中主線程中創建的線程可以獨立於主線程執行,也就是說main函數結束了。在main函數中產生的線程還在繼續執行,如果希望主線程在所有子線程都結束再結束,該怎么做呢?可以試想這樣一種場景:創建了50個線程,每個線程計算10000個數字之和,最后計算出總和。如果線程繼承了Runnable接口,每個線程就無法把結果返回,或許回想到使用全局變量來定義五十萬個數字的和,每個線程對這個全局變量進行操作,並通過鎖機制控制線程安全。這種方式還需要考慮一個問題就是,最后的結果怎么輸出?可以在主線程輸出嘛~,但是此時就涉及到主線程等待子線程的問題了?但是使用實現了Callable接口的線程類,就可以很優美的解決以上問題,讓每個線程類計算自己負責的部分,然后得出自己的結果,剛才有說,實現了Callable接口的線程可以返回結果,這樣我們就可以在主線程中將結果取出,此時取出結果的方法是個阻塞的方法,也就是該子線程如果沒有獲得結果會讓主線程一直等待在那里,這樣我們把每個線程的值取出后在主線程中計算出總和,最后輸出,這樣簡單明了。下面一個簡單的例子可以看出Callable如何使用,Callable還有其他特點,有興趣可以自行查閱。

/** Callable接口支持泛型,此處設置返回值類型為String*/

public class ClientThread implements Callable<String>{

/** 實現Runnable要復寫run方法,但實現Callable接口需要復寫call方法*/
@Override
public String call() {
  /** 此處寫你的邏輯處理*/

  StringBuilder builder = new StringBuilder();

  for(int i = 0; i < 4; i++)

  {

    builder.append((int)(Math.random()*10 + 1));  //產生1~9的隨機數;

  }

  return builder.toString();
}

 

public Class Test{  

  public static void main(String[] args)
  {
    List<Future<String>> list = new ArrayList<Future<String>>();  //Future<String>是線程池執行后產生的結果類型,通過該類型的對象可以獲取線程的返回的值
    ExecutorService pool = Executors.newFixedThreadPool(10);  //線程池,產生10個線程備用
    for(int i = 0; i < 10; i++)
    {
      ClientThread ct = new ClientThread();
      list.add(pool.submit(ct));
    }
    for(Future<String> f : list)
    {
      try {

          /** 該方法讓主線程阻塞,等待子線程返回結果*/
          System.out.println(f.get()); 
         } catch (InterruptedException | ExecutionException e) {
          log.error("在將線程結果帶出時出錯");
         }
    }
    pool.shutdownNow();
  }

}

關於線程池的使用方式不了解的可以百度一下。


免責聲明!

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



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