java 并发之(2)同步器(synchronize
发布时间: 2013-03-13 10:56:58 作者: rapoo
java 并发之(二)同步器(synchronizer)FutureTask 、Exchanger
4.FutureTask?
??? 我们先来学习一下JDK1.5 API中关于这个类的详细介绍:?
??? “取消的异步计算。利用开始和取消计算的方法、查询计算是否完成的方法和获取计算结果的方法,此类提供了对 Future 的基本实现。仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。?
可使用 FutureTask 包装 Callable 或 Runnable 对象。因为 FutureTask 实现了 Runnable,所以可将 FutureTask 提交给 Executor 执行。?
除了作为一个独立的类外,此类还提供了 protected 功能,这在创建自定义任务类时可能很有用。 “?
??? 应用举例:我们的算法中有一个很耗时的操作,在编程的是,我们希望将它独立成一个模块,调用的时候当做它是立刻返回的,并且可以随时取消的?
具体代码如下(参考 [JCIP])?
Java代码??
import?java.util.concurrent.Callable;??import?java.util.concurrent.ExecutionException;??import?java.util.concurrent.ExecutorService;??import?java.util.concurrent.Executors;??import?java.util.concurrent.FutureTask;????public?class?TestFutureTask?{????????public?static?void?main(String[]?args)?{??????????ExecutorService?exec=Executors.newCachedThreadPool();????????????????????FutureTask<String>?task=new?FutureTask<String>(new?Callable<String>(){//FutrueTask的构造参数是一个Callable接口??????????????@Override??????????????public?String?call()?throws?Exception?{??????????????????return?Thread.currentThread().getName();//这里可以是一个异步操作??????????????}});????????????????????????????try?{??????????????????exec.execute(task);//FutureTask实际上也是一个线程??????????????????String?result=task.get();//取得异步计算的结果,如果没有返回,就会一直阻塞等待??????????????????System.out.printf("get:%s%n",result);??????????????}?catch?(InterruptedException?e)?{??????????????????e.printStackTrace();??????????????}?catch?(ExecutionException?e)?{??????????????????e.printStackTrace();??????????????}??????}????}??
??? 总结:FutureTask其实就是新建了一个线程单独执行,使得线程有一个返回值,方便程序的编写?
5. Exchanger?
??? 我们先来学习一下JDK1.5 API中关于这个类的详细介绍:?
??? “可以在pair中对元素进行配对和交换的线程的同步点。每个线程将条目上的某个方法呈现给 exchange 方法,与伙伴线程进行匹配,并且在返回时接收其伙伴的对象。Exchanger 可能被视为 SynchronousQueue 的双向形式。Exchanger 可能在应用程序(比如遗传算法和管道设计)中很有用。 “?
??? 应用举例:有两个缓存区,两个线程分别向两个缓存区fill和take,当且仅当一个满了,两个缓存区交换?
??? 代码如下(参考了网上给的示例?? http://hi.baidu.com/webidea/blog/item/2995e731e53ad5a55fdf0e7d.html)?
Java代码??
import?java.util.ArrayList;??import?java.util.concurrent.Exchanger;????public?class?TestExchanger?{????????public?static?void?main(String[]?args)?{??????????final?Exchanger<ArrayList<Integer>>?exchanger?=?new?Exchanger<ArrayList<Integer>>();??????????final?ArrayList<Integer>?buff1?=?new?ArrayList<Integer>(10);??????????final?ArrayList<Integer>?buff2?=?new?ArrayList<Integer>(10);????????????new?Thread(new?Runnable()?{??????????????@Override??????????????public?void?run()?{??????????????????ArrayList<Integer>?buff?=?buff1;??????????????????try?{??????????????????????while?(true)?{??????????????????????????if?(buff.size()?>=?10)?{??????????????????????????????buff?=?exchanger.exchange(buff);//开始跟另外一个线程交互数据??????????????????????????????System.out.println("exchange?buff1");??????????????????????????????buff.clear();??????????????????????????}??????????????????????????buff.add((int)(Math.random()*100));??????????????????????????Thread.sleep((long)(Math.random()*1000));??????????????????????}??????????????????}?catch?(InterruptedException?e)?{??????????????????????e.printStackTrace();??????????????????}??????????????}??????????}).start();????????????????????new?Thread(new?Runnable(){??????????????@Override??????????????public?void?run()?{??????????????????ArrayList<Integer>?buff=buff2;??????????????????while(true){??????????????????????try?{??????????????????????????for(Integer?i:buff){??????????????????????????????System.out.println(i);??????????????????????????}??????????????????????????Thread.sleep(1000);??????????????????????????buff=exchanger.exchange(buff);//开始跟另外一个线程交换数据??????????????????????????System.out.println("exchange?buff2");??????????????????????}?catch?(InterruptedException?e)?{??????????????????????????e.printStackTrace();??????????????????????}??????????????????}??????????????}}).start();??????}??}??
??? 总结:Exchanger在特定的使用场景比较有用(两个伙伴线程之间的数据交互)?