2013-08-23 56 views
2

每當我運行我的程序實現可調用,我得到的順序形式的輸出。可調用是否按順序執行?

喜歡,這是我的程序:

package com.handson; 

import java.util.concurrent.ArrayBlockingQueue; 
import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.Future; 
import java.util.concurrent.RejectedExecutionException; 
import java.util.concurrent.ThreadPoolExecutor; 
import java.util.concurrent.TimeUnit; 

public class WorkSheet_1 implements Callable<String> { 

    /** 
    * @param args 
    */ 
    private int id; 
    static int count = 0; 
    public static String test[] = { "a1" , "a2" , "a3" , "a4" , "a5" , "a6" , "a7" , "a8" , 
            "b1" , "b2" , "b3" , "b4" , "b5" , "b6" , "b7" , "b8" , 
            "c1" , "c2" , "c3" , "c4" , "c5" , "c6" , "c7" , "c8" , 
            "d1" , "d2" , "d3" , "d4" , "d5" , "d6" , "d7" , "d8" , 
            "e1" , "e2" , "e3" , "e4" , "e5" , "e6" , "e7" , "e8" , 
            "f1" , "f2" , "f3" , "f4" , "f5" , "f6" , "f7" , "f8" , 
            "g1" , "g2" , "g3" , "g4" , "g5" , "g6" , "g7" , "g8" , 
            "h1" , "h2" , "h3" , "h4" , "h5" , "h6" , "h7" , "h8"}; 
    public WorkSheet_1(int id){ 
     this.id = id; 
    } 

    public static void main(String[] args) { 
     try{ 
     // TODO Auto-generated method stub 
      BlockingQueue blockingQueue = new ArrayBlockingQueue<WorkSheet_1>(48); 
      ThreadPoolExecutor testExecutor = new ThreadPoolExecutor(6, 10, 1, TimeUnit.SECONDS, blockingQueue); 
      for(int i = 0 ;i < test.length ;i++){ 
       Future<String> testFuture = testExecutor.submit(new WorkSheet_1(i)); 
       try { 
        System.out.println("Output Returned is : "+testFuture.get()); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (ExecutionException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }catch(RejectedExecutionException e){ 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public String call() throws Exception { 
     // TODO Auto-generated method stub 
     return "Called "+test[this.id]; 
    } 



} 

CALLABLE OUTPUT:

Output Returned is : Called a1 
Output Returned is : Called a2 
Output Returned is : Called a3 
Output Returned is : Called a4 
Output Returned is : Called a5 
Output Returned is : Called a6 
Output Returned is : Called a7 
Output Returned is : Called a8 
Output Returned is : Called b1 
Output Returned is : Called b2 
Output Returned is : Called b3 
Output Returned is : Called b4 
Output Returned is : Called b5 
Output Returned is : Called b6 
Output Returned is ............... 

輸出始終打印陣列順序而當我實現可運行輸出是按任意順序:

RUNNABLE OUTPUT:

Output Returned is : Called a1 
Output Returned is : Called a3 
Output Returned is : Called a7 
Output Returned is : Called a8 
Output Returned is : Called b1 
Output Returned is : Called b2 
Output Returned is : Called b3 
Output Returned is : Called b4 .............. 

Why such a difference ?

+0

順便說一下,由於Runnable不返回值,因此您的Runnable測試必須以不同的方式實現。如果您已經提供了該代碼,將會更清楚它爲什麼表現不同。 – ToolmakerSteve

回答

2

使用CompletionService我們不需要呼叫功能打印Sysout(由@Patricia如提供),並有使用CompletionService比期貨的好處。

欲瞭解更多信息,請參閱java-concurrency-executors-and-thread-pools。 陳述該網站,

「使用守則未來有點複雜。而且還有一個缺點,如果 第一個任務需要很長的時間來計算和所有其他任務 之前,首先結束時,當前線程這個問題的第一個任務ends.Solution之前不能計算結果 是完成服務」

現在使用的解決方案服務Sompletion打印所需的結果:

BlockingQueue<Runnable> blockingQueue blockingQueue = new ArrayBlockingQueue<WorkSheet_1>(48); 
    ThreadPoolExecutor testExecutor = new ThreadPoolExecutor(6, 16, 1, 
      TimeUnit.SECONDS, blockingQueue, new CustomThreadFactory()); 

    CompletionService<String> completionService = new ExecutorCompletionService<String>(
      testExecutor); 

    for (int i = 0; i < test.length; i++) { 
     completionService.submit(new WorkSheet_1(i)); 
    } 

    for (int i = 0; i < test.length; i++) { 
     try { 
      String result = completionService.take().get(); 
      System.out.println("Output Returned is : " + result); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (ExecutionException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     // Compute the result 
    } 
4

因爲你在等待調用的結果for循環:

System.out.println("Output Returned is : "+testFuture.get()); 

的的Future.get()方法將阻塞,直到結果可用。因此,只有在前一個結果可用後才能提交下一個Callable。

+0

我將其替換爲: WorkSheet_1 testing = new WorkSheet_1(i); \t \t \t \t testExecutor.submit(testing); (「Output Returned is:」+ test [testing.getId()]); 仍然相同的結果 – Prateek

+0

即時通訊不打印的ID,即時通訊打印在該位置陣列的值。看看@Patricia soln其中future.get沒有在循環中調用,但仍然輸出是連續的 – Prateek

4

要查看輸出的交錯,您需要進行兩項更改。

第一個基於上一個答案的是將等待完成的任務從排隊的循環移出。這樣做可以使Callables並行運行,而不是在每個之後強制等待返回值。返回值仍按照排隊順序進行報告。

第二個變化是讓每個Callable在運行時產生一些輸出。如果您僅在完成時從主線程輸出,則輸出必須按等待完成的順序進行。

因爲Runnable不會產生返回值,所以我確定測試的Runnable窗體實際上做了這兩個更改。他們必須在運行時提供自己的輸出,而不是返回結果。沒有理由等待他們每個人完成。

下面是測試程序,基於原來的程序,這些變化:

import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.ArrayBlockingQueue; 
import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.Future; 
import java.util.concurrent.RejectedExecutionException; 
import java.util.concurrent.ThreadPoolExecutor; 
import java.util.concurrent.TimeUnit; 

public class Test implements Callable<String> { 

    /** 
    * @param args 
    */ 
    private int id; 
    static int count = 0; 
    public static String test[] = { "a1", "a2", "a3", "a4", "a5", "a6", "a7", 
     "a8", 
     "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", 
     "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", 
     "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", 
     "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", 
     "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", 
     "g1", "g2", "g3", "g4", "g5", "g6", "g7", "g8", 
     "h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8" }; 

    public Test(int id) { 
    this.id = id; 
    } 

    public static void main(String[] args) { 
    try { 
     // TODO Auto-generated method stub 
     BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(
      48); 
     ThreadPoolExecutor testExecutor = new ThreadPoolExecutor(6, 10, 1, 
      TimeUnit.SECONDS, blockingQueue); 
     List<Future<String>> futures = new ArrayList<>(); 
     for (int i = 0; i < test.length; i++) { 
     Future<String> testFuture = testExecutor.submit(new Test(i)); 
     futures.add(testFuture); 
     } 
     for (Future<String> testFuture : futures) { 
     try { 
      System.out.println("Output Returned is : " + testFuture.get()); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (ExecutionException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     } 
    } catch (RejectedExecutionException e) { 
     e.printStackTrace(); 
    } 
    } 

    @Override 
    public String call() throws Exception { 
    System.out.println("Running " + test[this.id]); 
    return "Called " + test[this.id]; 
    } 

} 

示例輸出:

Running a1 
Running a3 
Running a2 
Running a4 
Running a5 
Running a6 
Running a7 
Running b1 
Running b5 
Running a8 
Running b7 
Running b6 
Running b2 
Running b4 
Running b3 
Running c4 
Running c3 
Running c2 
Running c1 
Running b8 
Running d1 
Running c8 
Running c7 
Running c6 
Output Returned is : Called a1 
Output Returned is : Called a2 
Output Returned is : Called a3 
Running c5 
Output Returned is : Called a4 
Running d6 
Running d5 
Running d4 
Running d3 
Running d2 
Running e3 
Running e2 
Running e1 
Running d8 
Output Returned is : Called a5 
Running d7 
Output Returned is : Called a6 
Running e8 
Running e7 
Running e6 
Running e5 
Running e4 
Running f5 
Running f4 
Running f3 
Running f2 
Output Returned is : Called a7 
Running f1 
Output Returned is : Called a8 
Running g2 
Running g1 
Running f8 
Running f7 
Running f6 
Running g7 
Running g6 
Running g5 
Running g4 
Output Returned is : Called b1 
Running g3 
Output Returned is : Called b2 
Running h4 
Running h3 
Running h2 
Running h1 
Running g8 
Running h8 
Running h7 
Running h6 
Output Returned is : Called b3 
Running h5 
Output Returned is : Called b4 
Output Returned is : Called b5 
Output Returned is : Called b6 
Output Returned is : Called b7 
Output Returned is : Called b8 
Output Returned is : Called c1 
Output Returned is : Called c2 
Output Returned is : Called c3 
Output Returned is : Called c4 
Output Returned is : Called c5 
Output Returned is : Called c6 
Output Returned is : Called c7 
Output Returned is : Called c8 
Output Returned is : Called d1 
Output Returned is : Called d2 
Output Returned is : Called d3 
Output Returned is : Called d4 
Output Returned is : Called d5 
Output Returned is : Called d6 
Output Returned is : Called d7 
Output Returned is : Called d8 
Output Returned is : Called e1 
Output Returned is : Called e2 
Output Returned is : Called e3 
Output Returned is : Called e4 
Output Returned is : Called e5 
Output Returned is : Called e6 
Output Returned is : Called e7 
Output Returned is : Called e8 
Output Returned is : Called f1 
Output Returned is : Called f2 
Output Returned is : Called f3 
Output Returned is : Called f4 
Output Returned is : Called f5 
Output Returned is : Called f6 
Output Returned is : Called f7 
Output Returned is : Called f8 
Output Returned is : Called g1 
Output Returned is : Called g2 
Output Returned is : Called g3 
Output Returned is : Called g4 
Output Returned is : Called g5 
Output Returned is : Called g6 
Output Returned is : Called g7 
Output Returned is : Called g8 
Output Returned is : Called h1 
Output Returned is : Called h2 
Output Returned is : Called h3 
Output Returned is : Called h4 
Output Returned is : Called h5 
Output Returned is : Called h6 
Output Returned is : Called h7 
Output Returned is : Called h8 

「跑步XX」消息,以便或多或少開始時,但很快就會失靈。

+0

即使那麼我得到相同的順序輸出 – Prateek

+0

你應該得到兩種類型的輸出。原始消息仍按照等待完成的順序顯示。還應該有「Running xx」形式的消息,其中xx是您的字符串之一。這些並不都是按順序出現的,至少在我的系統上運行它。我會附加一個示例輸出到答案。 –

+0

請更新您的答案,以便我能夠獲得更多清晰 – Prateek

相關問題