活动对象:
java中的线程比较 复杂和难以控制,但是有另一种不同的实现方式被称为活动对象,这些对像每个都维护着它自己的工作器和消息对列,并且所有的对象的请求都将进入对列排队,任何时刻都只能运行一个,所以当你向一个活动对象发消息时,这条消息为一个任务,该任务会插入到这个对列中去,等待运行。有了活动对象我们就可串化消息而不是任务。
示列:
package com.package21.active;import java.util.concurrent.*;import java.util.*;public class ActiveObjectDemo {@Overridepublic String toString() {return "ActiveObjectDemo{" +"ex=" + ex +'}';}private ExecutorService ex = Executors.newSingleThreadExecutor();//任何时刻都只有一个线程执行private void sleep() {try {TimeUnit.MILLISECONDS.sleep(10000);//休眠了一段时间} catch(InterruptedException e) {System.out.println("sleep() interrupted");}}public Future<Integer> calculateInt(final int x, final int y) {return ex.submit(new Callable<Integer>() {public Integer call() {sleep();//休眠一段时间System.out.println("starting " + x + " + " + y);sleep();//休眠一段时间return x + y;}});}public Future<Float> calculateFloat(final float x, final float y) {return ex.submit(new Callable<Float>() {//因为submit方法产生一个Future对象,但是这个对象直到任务完成后才会有一个结果。public Float call() {sleep();//休眠一段时间System.out.println("starting " + x + " + " + y);sleep();return x + y;}});}public void shutdown() { ex.shutdown(); }public static void main(String[] args) {ActiveObjectDemo d1 = new ActiveObjectDemo();List<Future<?>> results =new CopyOnWriteArrayList<>();for(float f = 0.0f; f < 1.0f; f += 0.2f) {results.add(d1.calculateFloat(f, f));}for(int i = 0; i < 5; i++) {results.add(d1.calculateInt(i, i));}System.out.println("All asynch calls made");System.out.println("集合的大小"+results.size());//只要集合的size>0就会进入到循环中去,只有future中的结果完成,才回去取出结果,并在集合中移除,减小size的值,直到为0才回退出循环while(results.size() > 0) {for(Future<?> f : results)if(f.isDone()) {//如果不为空才会取值try {System.out.println(f.get());} catch(Exception e) {throw new RuntimeException(e);}results.remove(f);//每成功取出值就会减少}}d1.shutdown();}}
示列详解:
上述程序中,只要调用计算的方法就会先返回一个Future对象,然后就会添加到集合中去,但是这个时候的future对象还没有完成数据的传送,所以调用isDone时便不无法进入到取值任务中。而且此时集合的size还是一直大于0,所以程序会一直进行循环,知道返回一个值,idDone为true才会去进行取值,同时在将该元素从集合中移除。future就是一个活动对象,每个没有完成数据传送的future对象就是一个个任务进入对列中等待。此时只要有一个future对象完成了数据传输,然后isDone为true便开始取值。
