2013-08-23 54 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

相关问题