Multithreading 什么样的;“事件总线”;春天用?内置,反应堆,阿克卡?
几周后我们将开始一个新的Spring4应用程序。我们想使用一些事件驱动架构。今年,我到处读有关“反应堆”的书,在网上寻找时,我偶然发现了“阿克卡” 因此,目前我们有3种选择:Multithreading 什么样的;“事件总线”;春天用?内置,反应堆,阿克卡?,multithreading,spring,akka,event-driven-design,project-reactor,Multithreading,Spring,Akka,Event Driven Design,Project Reactor,几周后我们将开始一个新的Spring4应用程序。我们想使用一些事件驱动架构。今年,我到处读有关“反应堆”的书,在网上寻找时,我偶然发现了“阿克卡” 因此,目前我们有3种选择: Spring的ApplicationEvent: 反应堆: Akka: 我找不到真正的比较 现在我们只需要像这样的东西: X注册以侦听事件E Y注册以侦听事件E Z发送事件E 然后X和Y将接收并处理事件 我们很可能会以异步方式使用它,但肯定也会有一些同步场景。我们很可能总是发送一个类作为事件。(Reactor示例
- Spring的
:ApplicationEvent
- 反应堆:
:Akka
现在我们只需要像这样的东西:
注册以侦听X
事件E
注册以侦听Y
事件E
发送Z
事件E
X
和Y
将接收并处理事件
我们很可能会以异步方式使用它,但肯定也会有一些同步场景。我们很可能总是发送一个类作为事件。(Reactor示例主要使用字符串和字符串模式,但也支持对象)
据我所知,
ApplicationEvent
默认情况下是同步工作的,Reactor
以异步方式工作。而且Reactor
还允许使用await()
方法使其有点同步Akka
提供与反应堆差不多的功能,但也支持远程处理
关于Reactor的await()
方法:它能等待多个线程完成吗?或者甚至是其中的一部分?如果我们从上面举个例子:
注册以侦听X
事件E
注册以侦听Y
事件E
发送Z
事件E
X
和Y
完成。是否可以让它只等待X
,而不等待Y
也许还有其他选择?比如JMS呢 很多问题,但希望你能提供一些答案 谢谢大家!
编辑:示例用例
wait
,因为我需要这些信息来继续我在主线程中的工作听起来我需要一个线程池或一个环形缓冲区。这些框架是否有动态的环形缓冲区,如果需要的话,它们的大小会增加?仔细定义您希望从框架中得到什么。如果一个框架的特性超过了您的需要,那么它并不总是好的。更多的特性意味着更多的bug,更多的代码需要学习,性能也会降低 一些值得关注的功能包括:
- 参与者的性质(线程或轻量级对象)
- 在机群上工作的能力(Akka)
- 持久消息队列(JMS)
- 特定功能,如信号(没有信息的事件)、转换(将不同端口的消息组合成复杂事件的对象,请参见Petri网)等
等待
,而不会导致线程不足
-信号、转换
附加组件:两种演员
通常,并行工作系统可以表示为一个图,其中活动节点相互发送消息。在Java中,与大多数其他主流语言一样,活动节点(参与者)可以实现为线程或由线程池执行的任务(可运行或可调用)。通常,参与者的一部分是线程,另一部分是任务。这两种方法各有优缺点,因此为系统中的每个参与者选择最合适的实现是至关重要的。
简单地说,线程可以阻塞(并等待事件),但会为其堆栈消耗大量内存。任务不能阻塞,而是使用共享堆栈(池中的线程)
若任务调用阻塞操作,它将从服务中排除池线程。如果许多任务阻塞,它们可能会排除所有线程,从而导致死锁-那些可以解除阻塞的任务无法运行。这种死锁称为线程饥饿。若为了防止线程不足,将线程池配置为无限,我们只需将任务转换为线程,就失去了任务的优势
为了消除对任务中阻塞操作的调用,任务应该分为两个(或多个)-第一个任务调用阻塞操作并退出,其余的任务被格式化为异步任务,在阻塞操作完成时启动。当然,阻塞操作必须有一个可选的异步接口。因此,例如,应该使用NIO或NIO2库,而不是同步读取套接字
不幸的是,标准java库缺少asynchro
@Autowired
Environment env;
@Autowired
SmtpClient client;
// Using a ThreadPoolDispatcher
Deferred<DomainObject, Stream<DomainObject>> input = Streams.defer(env, THREAD_POOL);
input.compose()
.map(new Function<DomainObject, EmailTemplate>() {
public EmailTemplate apply(DomainObject in) {
// generate the email
return new EmailTemplate(in);
}
})
.consume(new Consumer<EmailTemplate>() {
public void accept(EmailTemplate email) {
// send the email
client.send(email);
}
});
// Publish input into Deferred
DomainObject obj = reader.readNext();
if(null != obj) {
input.accept(obj);
}