Java
异步消息处理
在前一节实现异步调用的基础上
,
现在我们来看一下一个完善的
Java
异步消息处理机制
.
[
写在本节之前
]
在所有这些地方
,
我始终没有提到设计模式这个词
,
而事实上
,
多线程编程几乎每一步都在应该设计模式
.
你只要能恰如其份地应用它
,
为什么要在意你用了某某名称的模式呢
?
一个说书人它可以把武功招数说得天花乱坠
,
引得一班听书客掌声如雷
,
但他只是说书的
.
真正的武林高手也许并不知道自己的招式在说书人口中叫什么
,
这不重要
,
重要的是他能在最恰当的时机把他不知名的招式发挥到极致
!
你了解再多的设计模式
,
或你写出了此类的著作
,
并不重要
,
重要的是你能应用它设计出性能卓越的系统
.
本节的这个例子
,
如果你真正的理解了
,
不要怀疑自己
,
你已经是
Java
高手的行列了
.
如果你抛开本节的内容
,
五天后能自己独立地把它再实现一次
,
那你完全可以不用再看我写的文章系列了
,
至少是目前
,
我再也没有更高级的内容要介绍了
.
上节的
Java
异步调用为了简化调用关系
,
很多角色被合并到一个类中实现
,
为了帮助大家改快地抓住核心的流程
.
那么一个真正的异步消息处理器
,
当然不是这样的简单
.
一.
它要能适应不同类型的请求
:
本节用
makeString
来说明要求有返回值的请求
.
用
displayString
来说明不需要返回值的请求
.
二.
要能同时并发处理多个请求
,
并能按一定机制调度
:
本节将用一个队列来存放请求
,
所以只能按
FIFO
机制调度
,
你可以改用
LinkedList,
就可以简单实现一个优先级
(
优先级高的
addFirst,
低的
addLast).
三.
有能力将调用的边界从线程扩展到机器间
(RMI)
四.
分离过度耦合
,
如分离调用句柄
(
取货凭证
)
和真实数据的实现
.
分离调用和执行的过程
,
可以尽快地将调返回
.
现在看具体的实现
:
public interface Axman {
Result resultTest(int count,char c);
void noResultTest(String str);
}
这个接口有两个方法要实现
,
就是有返回值的调用
resultTest
和不需要返回值的调用
noResultTest,
我们把这个接口用一个代理类来实现
,
目的是将方法调用转化为对象
,
这样就可以将多个请求
(
多个方法调
)
放到一个容器中缓存起来
,
然后统一处理
,
因为
Java
不支持方法指针
,
所以把方法调用转换为对象
,
然后在这个对象上统一执行它们的方法
,
不仅可以做到异步处理
,
而且可以将代表方法调用的请求对象序列化后通过网络传递到另一个机器上执行
(RMI).
这也是
Java
回调机制最有力的实现
.
一个简单的例子
.
如果
1:
做
A
如果
2:
做
B
如果
3:
做
C
如果有
1000
个情况
,
你不至于用
1000
个
case
吧
?
以后再增加呢
?
所以如果
C/C++
程序员
,
会这样实现
: (c
和
c++
定义结构不同
)
type define struct MyStruct{
int mark;
(*fn) ();
} MyList;
然后你可以声明这个结构数据
:
{1,A,
2,B
3,C
}
做一个循环
:
for(i=0;i<length;i++) {
if(
数据组
[i].mark ==
传入的值
) (
数据组
[i].*fn)();
}
简单说
c/c++
中将要被调用的涵数可以被保存起来
,
然后去访问
,
调用
,
而
Java
中
,
我们无法将一个方法保存
,
除了直接调用
,
所以将要调用的方法用子类来实现
,
然后把这些子类实例保存起来
,
然后在这些子类的实现上调用方法
:
interface My{
void test();
}
class A implements My{
public void test(){
System.out.println(“A”):
}
}
class B implements My{
public void test(){
System.out.println(“B”):
}
}
class C implements My{
public void test(){
System.out.println(“C”):
}
}
class MyStruct {
int mark;
My m;
public MyStruct(int mark,My m){this.mark = amrk;this.m = m}
}
数组
:
{ new MyStruct(1,new A()),new MyStruct(2,new B()),new MyStruct(3,new C())}
for(xxxxxxxxx) if(
参数
==
数组
[i].mark)
数组
[i].m.test();
这样把要调用的方法转换为对象的保程不仅仅是可以对要调用的方法进行调度
,
而且可以把对象序列化后在另一台机器上执行
,
这样就把调用边界从线程扩展到了机器
.
回到我们的例子
:
class Proxy implements Axman{
private final Scheduler scheduler;
private final Servant servant;
public Proxy(Scheduler scheduler,Servant servant){
this.scheduler = scheduler;
this.servant = servant;
}
public Result resultTest(int count,char c){
FutureResult futrue = new FutureResult();
this.scheduler.invoke(new ResultRequest(servant,futrue,count,c));
return futrue;
}
public void noResultTest(String str){
this.scheduler.invoke(new NoResultRequest(this.servant,str));
}
}
其中
scheduler
是管理对调用的调度
, servant
是真正的对方法的执行
:
Servant
就是去真实地实现方法
:
class Servant implements Axman{
public Result resultTest(int count,char c){
char[] buf = new char[count];
for(int i = 0;i < count;i++){
buf[i] = c;
try{
Thread.sleep(100);
}catch(Throwable t){}
}
return new RealResult(new String(buf));
}
public void noResultTest(String str){
try{
System.out.println("displayString :" + str);
Thread.sleep(10);
}catch(Throwable t){}
}
}
在
scheduler
将方法的调用
(invkoe)
和执行
(execute)
进行了分离
,
调用就是开始
”
注册
”
方法到要执行的容器中
,
这样就可以立即返回出来
.
真正执行多久就是
execute
的事了
,
就象一个人点燃爆竹的引信就跑了
,
至于那个爆竹什么时候爆炸就不是他能控制的了
.
public class Scheduler extends Thread {
private final ActivationQueue queue;
public Scheduler(ActivationQueue queue){
this.queue = queue;
}
public void invoke(MethodRequest request){
this.queue.putRequest(request);
}
public void run(){
while(true){
//
如果队列中有请求线程
,
测开始执行请求
MethodRequest request = this.queue.takeRequest();
request.execute();
}
}
}
在
scheduler
中只用一个队列来保存代表方法和请求对象
,
实行简单的
FIFO
调用
,
你要实更复杂的调度就要在这里重新实现
:
class ActivationQueue{
private static final int MAX_METHOD_REQUEST = 100;
private final MethodRequest[] requestQueue;
private int tail;
private int head;
private int count;
public ActivationQueue(){
this.requestQueue = new MethodRequest[MAX_METHOD_REQUEST];
this.head = this.count = this.tail = 0;
}
public synchronized void putRequest(MethodRequest request){
while(this.count >= this.requestQueue.length){
try {
this.wait();
}
catch (Throwable t) {}
}
this.requestQueue[this.tail] = request;
tail = (tail + 1)%this.requestQueue.length;
count ++ ;
this.notifyAll();
}
public synchronized MethodRequest takeRequest(){
while(this.count <= 0){
try {
this.wait();
}
catch (Throwable t) {}
}
MethodRequest request = this.requestQueue[this.head];
this.head = (this.head + 1) % this.requestQueue.length;
count --;
this.notifyAll();
return request;
}
}
为了将方法调用转化为对象
,
我们通过实现
MethodRequest
对象的
execute
方法来方法具体方法转换成具体对象
:
abstract class MethodRequest{
protected final Servant servant;
分享到:
相关推荐
### Java异步消息处理知识点详解 #### 一、适应不同类型的请求 在Java异步消息处理中,系统设计需要能够适应不同类型的请求。这通常包括两种类型:一种是有返回值的请求,另一种是没有返回值的请求。 - **有...
总结起来,JavaEE异步消息处理通过JMS和消息队列实现了客户端和服务端之间的解耦和高效通信,利用线程池和异步处理提升了系统的并发性和响应能力。开发者可以利用各种框架和工具,如EJB的MDB或Spring的JMS支持,轻松...
能同时并发处理多个请求,并能按一定机制调度: 用一个队列来存放请求,所以只能按FIFO机制调度,你可以改用LinkedList,就可以简单实现一个优先级(优先级高的addFirst,低的addLast). 三.有能力将调用的边界从线程扩展到...
在Android开发中,异步消息处理是一种常见的多线程编程技术,主要用于解决UI线程(主线程)与后台任务之间的通信问题。标题“异步消息处理线程”着重强调了这种处理方式,它允许开发者在不阻塞主线程的情况下执行...
Callback是最原始的异步处理方式,通过为被调用函数设置回调函数,当被调用函数执行完成后,调用这个回调函数来处理结果。这种方式的缺点是控制权反转,增加了代码的复杂性。 Java中使用Future来处理异步操作,但它...
Java异步通信是一种提高应用程序效率和响应速度的技术,它允许程序在等待IO操作完成时执行其他任务,而不是阻塞等待。在这个示例中,我们主要关注的是Java NIO(非阻塞I/O)和异步Socket。NIO是Java SE 1.4引入的一...
Java异步调用转同步方法实例详解 Java异步调用转同步方法实例详解是指在Java中将异步调用转换为同步调用的技术,主要用于解决异步调用过程中的阻塞问题。异步调用是一种非阻塞的调用方式,调用方在调用过程中,不...
总结起来,Java文件异步上传是一个涉及前端JavaScript插件和后端Java服务器处理的复杂过程。`jQuery.uploadify`提供了一个方便的工具来实现这一功能,而Java端则需要编写相应的接口来接收并处理上传的文件。理解并...
Java中的HTTP异步请求是一种高效的网络通信方式,它允许程序在发送HTTP请求后不等待响应,而是立即继续执行其他任务,当服务器响应时,通过回调函数处理结果。这种方式避免了同步请求时线程阻塞的问题,提高了应用的...
Java异步处理机制实例详解 Java异步处理机制是一种常见的编程技术,用于提高程序的性能和响应速度。异步处理机制的核心思想是将某个处理过程分解成多个线程同时处理,以提高处理速度和效率。下面将对Java异步处理...
在IT行业中,尤其是在Java开发领域,异步处理和事务管理是两个重要的概念,它们对于提升系统性能和保证数据一致性起着关键作用。本篇将详细探讨如何使用Starling这一分布式消息队列来实现异步处理事务。 首先,...
### Android中异步消息处理...Looper负责创建消息循环并在循环中处理消息,MessageQueue用于存储消息,而Handler则作为消息的发送者和接收者。掌握这些基本概念对于理解和解决Android应用程序中的多线程问题至关重要。
### JAVA异步通信教程 #### 一、JAVA NIO2 异步通道概述 随着JAVA 7的发布,异步通信成为了开发高性能服务器程序的重要工具之一。为了更好地理解和使用JAVA 7提供的NIO2(New Input/Output)异步通道功能,本教程...
3. 消息积压:大量未处理消息可能导致队列积压,需监控并采取扩容、优化处理逻辑等措施。 总结,电商领域的异步消息系统是提高系统效率和稳定性的重要手段,理解其原理和实践是构建高效电商平台的关键。在设计和...
### Java异步技术原理与实践 #### 一、引言 在现代软件开发尤其是微服务架构下,系统之间复杂的依赖关系和技术挑战日益增加。本文旨在深入探讨Java中的异步技术,包括其背后的原理以及如何在实际场景中运用这些...
Java异步技术是现代软件开发中的重要组成部分,尤其在高并发、高性能的系统设计中扮演着关键角色。本文将深入探讨Java异步技术的原理,包括阻塞与非阻塞I/O、轮询机制以及I/O多路复用,并结合实践进行详细讲解。 一...
在 Java 中实现异步 socket 通讯是一种高效的方式,尤其是在需要实时处理大量数据时。下面我们将详细介绍异步 socket 类的实现和源代码。 首先,我们需要了解 Java 中的 socket 类是如何工作的。通常情况下,Java ...
在Java编程中,异步加载图片是一项常见的任务,特别是在开发Android或者Web应用时,为了提高用户体验,我们需要在后台线程中加载图片,而不是阻塞主线程。本篇将深入讲解如何利用Java原生类实现Http异步加载图片的...
通过这种方式,消息分发器可以确保消息的有序处理,避免单个组件的过载,同时允许系统以异步方式工作,提高整体性能。 在Java环境中,消息分发常常与Java消息服务(Java Message Service,JMS)和消息中间件如...
Java异步服务器是一种高效处理多个客户端连接的技术,它与传统的同步服务器模型相比,具有更高的并发性和资源利用率。在Java中实现异步服务器,通常会利用NIO(Non-blocking Input/Output)或者Java 7引入的AIO...