2016-10-02 14 views
0

Here is the java.util.concurrent.FutureTask doc page,這裏我使用lambda表達式而沒有創建Callable實現類,這裏是我的代碼只是想測試可調用接口如何工作,但結果讓我不滿意。java callable接口如何執行多任務

import java.util.concurrent.*; 
public class CallableTest{ 
    public static void main(String[] args){ 
     FutureTask<Integer> ft = new FutureTask<Integer>((Callable<Integer>)() -> { 
      int i = 0; 
      for(; i < 100; i++){ 
       System.out.println(Thread.currentThread().getName() + "\t"+ i); 
      } 
      return i; 
     }); 
     for(int i = 0; i < 100; i++){ 
      System.out.println(Thread.currentThread().getName() + "\t" + i); 
      if(i == 20){ 
       new Thread(ft, "有返回值的線程").start(); 
       new Thread(ft, "會不會執行呢?").start(); 
      } 
     } 
     try{ 
      System.out.println("The result of ft is " + ft.get()); 
     }catch(Exception e){System.out.println(e);} 
    } 
} 

結果表明通過new Thread(ft, "會不會執行呢?").start();制螺紋從未執行不管迭代次數爲100或什麼的。這就是爲什麼?我已經google了這個問題,但他們都說使用ThreadPool,但我認爲如果這兩個簡單的線程無法工作,threadpool將不會。

回答

2

FutureTask保持與以下轉變的state

* Possible state transitions: 
* NEW -> COMPLETING -> NORMAL 
* NEW -> COMPLETING -> EXCEPTIONAL 
* NEW -> CANCELLED 
* NEW -> INTERRUPTING -> INTERRUPTED 

如果狀態不是NEW,它run方法只是返回:

public void run() { 
     if (state != NEW || 
      !UNSAFE.compareAndSwapObject(this, runnerOffset, 
            null, Thread.currentThread())) 
      return; 
     .... 
    } 

因此,需要爲每個線程單獨FutureTask實例因爲ft在第一個線程執行後的狀態不是NEW

下面的代碼執行兩個線程:

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

    public class FutureTask { 

    public static void main(String[] args) { 
     FutureTask<Integer> ft = getFutureTask(); 
     FutureTask<Integer> ft2 = getFutureTask(); 
     new Thread(ft, "有返回值的線程").start(); 
     new Thread(ft2, "會不會執行呢?").start(); 
     try{ 
      System.out.println("The result of ft is " + ft.get()); 
     }catch(Exception e){System.out.println(e);} 
     try{ 
      System.out.println("The result of ft2 is " + ft2.get()); 
     }catch(Exception e){System.out.println(e);} 
    } 

    private static FutureTask<Integer> getFutureTask() { 
     return new FutureTask<Integer>((Callable<Integer>)() -> { 
      int i = 0; 
      for(; i < 100; i++){ 
       System.out.println(Thread.currentThread().getName() + "\t"+ i); 
      } 
      return i; 
     }); 
    } 
+0

如果我要實例化一個FutureTask每個任務每一次,它不應該,因爲多個FutureTask實例不是一個擔任Task.eh定義爲多線程,在這裏我想對你的答案做一些修改,我認爲如果Callable接口已經實現並且每個FutureTask都將這個實現作爲構造參數,那麼會出現多線程思想。 – Crabime