活动对象:
java中的线程比较 复杂和难以控制,但是有另一种不同的实现方式被称为活动对象,这些对像每个都维护着它自己的工作器和消息对列,并且所有的对象的请求都将进入对列排队,任何时刻都只能运行一个,所以当你向一个活动对象发消息时,这条消息为一个任务,该任务会插入到这个对列中去,等待运行。有了活动对象我们就可串化消息而不是任务。
示列:
package com.package21.active;
import java.util.concurrent.*;
import java.util.*;
public class ActiveObjectDemo {
@Override
public 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便开始取值。