Java7 ForkJoin入门实例

来源:互联网 发布:android 全局网络监听 编辑:程序博客网 时间:2024/05/29 06:26

本文转自:http://www.xiaoyaochong.net/wordpress/?p=314

Java7引入了Fork Join的概念,来更好的支持并行运算。顾名思义,Fork Join类似与流程语言的分支,合并的概念。也就是说Java7 SE原生支持了在一个主线程中开辟多个分支线程,并且根据分支线程的逻辑来等待(或者不等待)汇集,当然你也可以fork的某一个分支线程中再开辟Fork Join,这也就可以实现Fork Join的嵌套。

有两个核心类ForkJoinPool和ForkJoinTask。

ForkJoinPool实现了ExecutorService接口,起到线程池的作用。所以他的用法和Executor框架的使用时一样的,当然Fork Join本身就是Executor框架的扩展。ForkJoinPool有3个关键的方法,来启动线程,execute(...),invoke(...),submit(...)。具体描述如下:

 客户端非fork/join调用内部调用fork/join异步执行execute(ForkJoinTask)ForkJoinTask.fork等待获取结果invoke(ForkJoinTask)ForkJoinTask.invoke执行,获取Futruesubmit(ForkJoinTask)ForkJoinTask.fork(ForkJoinTasks are Futures)

 

 ForkJoinTask是分支合并的执行任何,分支合并的业务逻辑使用者可以再继承了这个抽先类之后,在抽象方法exec()中实现。其中exec()的返回结果和ForkJoinPool的执行调用方(execute(...),invoke(...),submit(...)),共同决定着线程是否阻塞,具体请看下面的测试用例。

首先,用户需要创建一个自己的ForkJoinTask。代码如下:

Java代码  收藏代码
  1. public class MyForkJoinTask<V> extends ForkJoinTask<V> {  
  2.   
  3.     /** 
  4.      *  
  5.      */  
  6.     private static final long serialVersionUID = 1L;  
  7.       
  8.     private V value;  
  9.       
  10.     private boolean success = false;  
  11.       
  12.     @Override  
  13.     public V getRawResult() {  
  14.         return value;  
  15.     }  
  16.   
  17.     @Override  
  18.     protected void setRawResult(V value) {  
  19.         this.value = value;  
  20.     }  
  21.   
  22.     @Override  
  23.     protected boolean exec() {  
  24.         System.out.println("exec");  
  25.         return this.success;  
  26.     }  
  27.   
  28.     public boolean isSuccess() {  
  29.         return success;  
  30.     }  
  31.   
  32.     public void setSuccess(boolean isSuccess) {  
  33.         this.success = isSuccess;  
  34.     }  
  35.   
  36. }  

 

测试ForkJoinPool.invoke(...):

Java代码  收藏代码
  1. @Test  
  2.     public void testForkJoinInvoke() throws InterruptedException, ExecutionException {  
  3.         ForkJoinPool forkJoinPool = new ForkJoinPool();  
  4.         MyForkJoinTask<String> task = new MyForkJoinTask<String>();  
  5.         task.setSuccess(true);  
  6.         task.setRawResult("test");  
  7.         String invokeResult = forkJoinPool.invoke(task);  
  8.         assertEquals(invokeResult, "test");  
  9.     }  
  10.       
  11.     @Test  
  12.     public void testForkJoinInvoke2() throws InterruptedException, ExecutionException {  
  13.         final ForkJoinPool forkJoinPool = new ForkJoinPool();  
  14.         final MyForkJoinTask<String> task = new MyForkJoinTask<String>();  
  15.         new Thread(new Runnable() {  
  16.             public void run() {  
  17.                 try {  
  18.                     Thread.sleep(1000);  
  19.                 } catch (InterruptedException e) {  
  20.                 }  
  21.                   
  22.                 task.complete("test");  
  23.             }  
  24.         }).start();  
  25.           
  26.         // exec()返回值是false,此处阻塞,直到另一个线程调用了task.complete(...)  
  27.         String result = forkJoinPool.invoke(task);  
  28.         System.out.println(result);  
  29.     }  
  30.       
  31.     @Test  
  32.     public void testForkJoinSubmit() throws InterruptedException, ExecutionException {  
  33.         final ForkJoinPool forkJoinPool = new ForkJoinPool();  
  34.         final MyForkJoinTask<String> task = new MyForkJoinTask<String>();  
  35.           
  36.         task.setSuccess(true); // 是否在此任务运行完毕后结束阻塞  
  37.         ForkJoinTask<String> result = forkJoinPool.submit(task);  
  38.         result.get(); // 如果exec()返回值是false,在此处会阻塞,直到调用complete  
  39.     }  

 

测试ForkJoinPool.submit(...):

Java代码  收藏代码
  1. @Test  
  2.     public void testForkJoinSubmit() throws InterruptedException, ExecutionException {  
  3.         final ForkJoinPool forkJoinPool = new ForkJoinPool();  
  4.         final MyForkJoinTask<String> task = new MyForkJoinTask<String>();  
  5.           
  6.         task.setSuccess(true); // 是否在此任务运行完毕后结束阻塞  
  7.         ForkJoinTask<String> result = forkJoinPool.submit(task);  
  8.         result.get(); // 如果exec()返回值是false,在此处会阻塞,直到调用complete  
  9.     }  
  10.       
  11.     @Test  
  12.     public void testForkJoinSubmit2() throws InterruptedException, ExecutionException {  
  13.         final ForkJoinPool forkJoinPool = new ForkJoinPool();  
  14.         final MyForkJoinTask<String> task = new MyForkJoinTask<String>();  
  15.           
  16.         forkJoinPool.submit(task);  
  17.         Thread.sleep(1000);  
  18.     }  
  19.       
  20.     @Test  
  21.     public void testForkJoinSubmit3() throws InterruptedException, ExecutionException {  
  22.         final ForkJoinPool forkJoinPool = new ForkJoinPool();  
  23.         final MyForkJoinTask<String> task = new MyForkJoinTask<String>();  
  24.         new Thread(new Runnable() {  
  25.             public void run() {  
  26.                 try {  
  27.                     Thread.sleep(1000);  
  28.                 } catch (InterruptedException e) {  
  29.                 }  
  30.                   
  31.                 task.complete("test");  
  32.             }  
  33.         }).start();  
  34.           
  35.         ForkJoinTask<String> result = forkJoinPool.submit(task);  
  36.         // exec()返回值是false,此处阻塞,直到另一个线程调用了task.complete(...)  
  37.         result.get();   
  38.         Thread.sleep(1000);  
  39.     }  

 

测试ForkJoinPool.execute(...):

Java代码  收藏代码
  1. @Test  
  2.    public void testForkJoinExecute() throws InterruptedException, ExecutionException {  
  3.        ForkJoinPool forkJoinPool = new ForkJoinPool();  
  4.        MyForkJoinTask<String> task = new MyForkJoinTask<String>();  
  5.        forkJoinPool.execute(task); // 异步执行,无视task.exec()返回值。  
  6.    }  
0 0
原创粉丝点击