目的:要实现具有自己的控制机制线程并仅公开其API而不公开自己的执行,我们可以使用活动对象模式。
活动对象设计模式使每个驻留在其控制线程中的对象的方法执行与方法调用脱钩。 目的是通过使用异步方法调用和用于处理请求的调度程序来引入并发。
活动对象模式有助于解决同步困难,而无需使用“synchronized”方法。活动对象将包含线程安全数据结构(如BlockingQueue),并通过移动方法的逻辑来同步方法调用并将其存储在DSA中。
类图:
代码示例:
1.创建活动对象抽象类
public abstract class ActiveCreature {
private static final Logger logger = LoggerFactory.getLogger(ActiveCreature.class.getName());
private BlockingQueue<Runnable> requests;
private String name;
private Thread thread;
public ActiveCreature(String name) {
this.name = name;
this.requests = new LinkedBlockingQueue<Runnable>();
thread = new Thread(() -> {
while (true) {
try {
requests.take().run();
} catch (InterruptedException e) {
logger.error(e.getMessage());
}
}
});
thread.start();
}
public void eat() throws InterruptedException {
requests.put(() -> {
logger.info("{} is eating!", name);
logger.info("{} has finished eating!", name);
});
}
@SneakyThrows
public void roam() {
requests.put(() -> {
logger.info("{} has started to roam and the wastelands.", name);
});
}
public String name( ){
return this.name;
}
}
2.创建子类继承
public class Orc extends ActiveCreature{
public Orc(String name) {
super(name);
}
}
3.测试
public class App implements Runnable {
public static final Logger logger = LoggerFactory.getLogger(App.class.getName());
public static final int NUM_CREATURES = 3;
public static void main(String args[]) {
App app = new App();
app.run();
}
@Override
public void run() {
ArrayList<ActiveCreature> creatures = new ArrayList<>();
try {
for (int i = 0; i < NUM_CREATURES; i++) {
creatures.add(new Orc(Orc.class.getSimpleName()+i));
creatures.get(i).eat();
creatures.get(i).roam();
}
Thread.sleep(1000);
} catch (InterruptedException e) {
logger.error(e.getMessage());
Thread.currentThread().interrupt();
}
Runtime.getRuntime().exit(1);
}
}
结果:
Orc1 is eating!
Orc2 is eating!
Orc0 is eating!
Orc2 has finished eating!
Orc1 has finished eating!
Orc0 has finished eating!
Orc2 has started to roam and the wastelands.
Orc1 has started to roam and the wastelands.
Orc0 has started to roam and the wastelands.