实际上是通过BlockingQueue 来保证同一个线程下 任务之间的线程安全(顺序执行)。
不同线程之间 仍然是线程不安全的。
参考文档:
活动对象的特征:
基于消息机制:对活动对象的请求和可能的参数都被转化为消息,这些消息被转发给活动对象实际实现并排队等待处理。处理结果以future对象返还给提出请求的对象。
异步调用:对活动对象的请求被异步执行,实际由活动对象的工作线程处理请求,故不会阻塞调用者。仅当请求未完成执行时,调用者试图获取处理结果时会被阻塞。
线程安全:活动对象天生是线程安全的。因为他顺序地从请求队列摘取消息进行处理,并且始终在一个单独的线程中执行,由于不存在资源竞争,所以也不用担心同步、死锁等问题。同步仍旧会发生,但它通过将方法调用排队,使得任何时刻都只能发生一个调用,从而将同步控制在消息的级别上发生。
活动对象的应用场景:
适合于实时跟踪具有按某一特定顺序执行而又互不影响的多线程任务其执行状况的情景
————————————————
版权声明:本文为CSDN博主「zcc_0015」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zcc_0015/article/details/15502813
应用场景理解:
我想到的是用在 对于业务的复杂逻辑产生的响应慢的问题的优化 上面。 有点类似@Async的使用场景
假设 同一个接口下 存在以下情况:
① 第一个任务 查询表A的数据 数据处理 更新表B -》 第二个任务 根据数据处理后的数据 数据处理
②查询表C的数据 数据处理 更新表D
上述①和②就是两个活动对象。 其中①中有队列中存在两个runnable ②的队列中中只有一个runnable
代码来源开源项目: https://github.com/iluwatar/java-design-patterns
public abstract class ActiveCreature {
private static final Logger logger = LoggerFactory.getLogger(ActiveCreature.class.getName());
private BlockingQueue<Runnable> requests;
private String name;
private Thread thread; // Thread of execution.
private int status; // status of the thread of execution.
/**
* 初始化活动对象 实际上是起一个线程 在活动状态为0的情况下不断遍历队列(如果队列中无元素那么take()方法会阻塞线程)
*/
protected ActiveCreature(String name) {
this.name = name;
this.status = 0;
this.requests = new LinkedBlockingQueue<>();
thread = new Thread(() -> {
boolean infinite = true;
while (infinite) {
try {
requests.take().run();
} catch (InterruptedException e) {
if (this.status != 0) {
logger.error("Thread was interrupted. --> {}", e.getMessage());
}
infinite = false;
Thread.currentThread().interrupt();
}
}
});
thread.start();
}
/**
* 吃 的任务 也就是将 一个任务条件到队列 这个动作封装成方法
*/
public void eat() throws InterruptedException {
requests.put(() -> {
logger.info("{} is eating!",name());
logger.info("{} has finished eating!",name());
});
}
/**
* 同上
*/
public void roam() throws InterruptedException {
requests.put(() ->
logger.info("{} has started to roam in the wastelands.",name())
);
}
public String name() {
return this.name;
}
/**
* 停止 活动对象
*/
public void kill() {
this.status = 1;
this.thread.interrupt();
}
/**
* 获取活动对象当前状态
*/
public int getStatus() {
return this.status;
}
}
public class Orc extends ActiveCreature {
public Orc(String name) {
super(name);
}
}
public class App implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(App.class.getName());
private static final int NUM_CREATURES = 3;
/**
* Program entry point. * * @param args command line arguments.
*/ public static void main(String[] args) {
var app = new App();
app.run();
}
@Override
public void run() {
List<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();
} finally {
for (int i = 0;i < NUM_CREATURES;i++) {
creatures.get(i).kill();
}
}
}
}