Java 同步异步任务的最佳方法
我的问题是:我已经将802.15.4无线网络连接到一个串行端口(使用包装器)。 我可以将包发送到网络中并侦听传入的包。 可以想象,这是高度异步的 任务来了:我想向网络发送命令,并在一个函数调用中等待响应。例如:我想从网络ID为1338的节点获取温度Java 同步异步任务的最佳方法,java,multithreading,synchronisation,Java,Multithreading,Synchronisation,我的问题是:我已经将802.15.4无线网络连接到一个串行端口(使用包装器)。 我可以将包发送到网络中并侦听传入的包。 可以想象,这是高度异步的 任务来了:我想向网络发送命令,并在一个函数调用中等待响应。例如:我想从网络ID为1338的节点获取温度 double getTemperature(int id) throws Exception { .... } 除了做这些“同步(对象)等待(…)通知(…)”的工作之外,还有更好的方法等待响应消息吗 致以最良好的祝愿, 比格博尼 也许可以添加一些香
double getTemperature(int id) throws Exception { .... }
除了做这些“同步(对象)等待(…)通知(…)”的工作之外,还有更好的方法等待响应消息吗
致以最良好的祝愿,
比格博尼
也许可以添加一些香料:
这一切都应该在一个webinterface中结束,用户可以在其中请求这些命令(通过ajax或直接)。我还想过在数据库中缓存responce值。
但是对于某些命令,您可以直接回答成功/失败更好的方法是将其封装在一些可重用的请求/响应类中。通过这种方式,您可以使用标准方式查询串行端口并等待响应。然而,这个类无疑必须在其实现的某处使用synchronized关键字和wait和notify命令。这是编写Java的关键部分,了解它们是如何工作的非常重要 如果你要像你说的那样设计一个函数,你必须确保你从一个线程调用它,这个线程可以阻止等待结果。函数必须在其内部实现某种等待循环,等待来自串行端口的响应。因此,无论它运行在哪个线程上,都必须能够等待,这一点很重要 这也带来了另外一点。如果有多个线程执行此操作,则需要有一个类来处理串行端口通信,该类可以处理来自多个线程的多个请求,并根据需要对它们进行排队,以处理串行端口和所连接的特定设备的异步性质。例如,在完全读取第一个命令的响应之前发送第二个命令可能不合适
这里有几个复杂的问题,重要的是要有一个好的设计,以合理的方式解决所有这些问题。我不确定我是否正确理解了这个问题,但我通常使用a来完成这类任务 在内部,
Future
实现使用wait和notify以及所有这些,但是接口本身变得相当干净
Future<Double> getTemperature(int id);
未来获取温度(int-id);
在通信代码中,您可以将传入的消息映射到未实现的未来。如果订购得到保证,你可以做如下事情
class Something {
Map<Integer, Queue<Object>> requests;
synchronized Future<?> request(int id, Object data) {
MyFutureImpl future = new MyFuture();
requests.get(id).add(future);
serializeAndSend(id, data);
return future;
}
void serializeAndSend(id, data) {...}
synchronized void response(int id, Object data) {
MyFutureImpl future = requests.get(id).remove();
future.setValue(data); // This would fulfill the future, and any
// threads waiting in a get() will get the
// value and continue.
}
}
分类{
地图请求;
已同步的未来请求(int-id,对象数据){
MyFutureImpl future=新建MyFuture();
请求.get(id).add(future);
序列化和发送(id、数据);
回归未来;
}
无效序列化发送(id,数据){…}
同步的void响应(int-id,对象数据){
MyFutureImpl future=requests.get(id.remove();
future.setValue(data);//这将满足未来以及任何
//在get()中等待的线程将获得
//重视并继续。
}
}
其中MyFutureImpl是一个非常基本的未来实现。我假设有一个通信线程在收到数据包时调用response()
。我还假设serializeAndSend()
-函数处理对客户端或块的写入,直到可以执行写入操作或将其传递给通信线程
使用支持并发的映射和队列结构可能会使一些
同步变得不必要。如果每个id只有一个未完成的呼叫,那么队列当然就没有必要了。您可以使用BlockingQueue执行此操作,这样您就不必手动管理任何同步。请求可以发送消息,然后在BlockingQueue上调用take(),该队列将等待元素出现。元素是在返回应答时由端口上的任何侦听器插入队列的应答
您只需进行协调,以便侦听器和请求者共享同一队列。对于每个请求,您只需要一个大小为1的队列来支持此场景
// Send method
BlockingQueue<Reply> q = new ArrayBlockingQueue<Reply>(1);
serialCom.registerQueue(myRequest.getId());
serialCom.sendRequest(myRequest);
return q.take();
//Listener
BlockingQueue<Reply> q = queueMap.get(incomingMessage.getId());
q.add(incomingMessage.getReply());
//发送方法
BlockingQueue q=新阵列BlockingQueue(1);
registerQueue(myRequest.getId());
serialCom.sendRequest(myRequest);
返回q.take();
//听众
BlockingQueue q=queueMap.get(incomingMessage.getId());
q、 添加(incomingMessage.getReply());
OK。这个问题更多地指向“是否有一些很酷的java技巧可以解决这个问题?”感谢您的输入。这让我回到纸和笔:)这正是我一直在寻找的“特殊Java东西”!