Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同步异步任务的最佳方法_Java_Multithreading_Synchronisation - Fatal编程技术网

Java 同步异步任务的最佳方法

Java 同步异步任务的最佳方法,java,multithreading,synchronisation,Java,Multithreading,Synchronisation,我的问题是:我已经将802.15.4无线网络连接到一个串行端口(使用包装器)。 我可以将包发送到网络中并侦听传入的包。 可以想象,这是高度异步的 任务来了:我想向网络发送命令,并在一个函数调用中等待响应。例如:我想从网络ID为1338的节点获取温度 double getTemperature(int id) throws Exception { .... } 除了做这些“同步(对象)等待(…)通知(…)”的工作之外,还有更好的方法等待响应消息吗 致以最良好的祝愿, 比格博尼 也许可以添加一些香

我的问题是:我已经将802.15.4无线网络连接到一个串行端口(使用包装器)。 我可以将包发送到网络中并侦听传入的包。 可以想象,这是高度异步的

任务来了:我想向网络发送命令,并在一个函数调用中等待响应。例如:我想从网络ID为1338的节点获取温度

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东西”!