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_Thread Safety - Fatal编程技术网

在java中在线程之间来回发送对象?

在java中在线程之间来回发送对象?,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,我有多个客户端处理程序线程,这些线程需要将接收到的对象传递给服务器队列,服务器队列将把另一种类型的对象传递回发送线程。服务器队列已启动,并在服务器启动时保持运行。我不确定将对象发送回的客户端处理程序线程使用哪种线程机制。我不打算使用socket或写入文件。在Java中使对象可访问方面,多线程和单线程之间没有区别。您只需遵循范围规则(public、private、protected),仅此而已。多个线程都在同一个进程中运行,因此不需要了解任何特殊的仅线程作用域规则 例如,定义一个传入对象的方法,并

我有多个客户端处理程序线程,这些线程需要将接收到的对象传递给服务器队列,服务器队列将把另一种类型的对象传递回发送线程。服务器队列已启动,并在服务器启动时保持运行。我不确定将对象发送回的客户端处理程序线程使用哪种线程机制。我不打算使用socket或写入文件。

在Java中使对象可访问方面,多线程和单线程之间没有区别。您只需遵循范围规则(public、private、protected),仅此而已。多个线程都在同一个进程中运行,因此不需要了解任何特殊的仅线程作用域规则

例如,定义一个传入对象的方法,并使该方法可以从另一个线程访问。要传递的对象只需从另一个线程的作用域中访问即可

就线程安全而言,在大多数情况下,这将解决问题。代码越复杂,线程安全可能会有点麻烦,但我认为这会让您开始

处理对象并生成结果对象的一种方法是使用共享数组或链接列表,该数组或链接列表充当对象队列,包含要处理的对象以及该处理的结果对象。如果没有更多关于您要做什么的细节,就很难深入到更多的细节,但是线程之间对对象的大多数共享访问归结为线程间方法调用,或者一些共享的对象集合/队列。

只需使用simple

现在可以在第二个线程中执行
callback.setData(…)

我觉得这是最安全的方法。其他解决方案包括使用
volatile
或某种共享对象,我认为这样做太过分了


您可能还希望使用这两个线程并将其传递给每个线程。如果您计划有多个线程,那么这可能是一个更好的解决方案

除非您完全确定它一次只能是一个对象,否则请使用某种队列


如果您确定它一次只能是一个对象,请使用某种队列。:-)

如果您想进行实际的消息传递,请查看。每个线程都有对队列的引用,并将等待直到一个线程通过队列传递引用

这将是线程安全的,并满足您的需求

如果你只是想让线程读写一个共享变量,你可以使用normalocity的建议,尽管它的线程安全性取决于你访问它的方式(通过同步或volatile)

  • 使用java.util.concurrent.*中的并发队列
为什么??几乎可以保证提供比任何手工轧制的产品更好的总体性能

建议:使用绑定队列,您将免费获得回压

注意:队列的深度决定了您的一般延迟特征:较浅的队列将以降低带宽为代价降低延迟

  • 使用未来语义
为什么??未来为获得异步结果提供了一种经过验证的标准方法

建议:创建一个简单的请求类并公开一个方法#getFutureSponse()。该方法的实现可以使用多种信令策略,例如锁、标志(使用原子/CAS)等


注意:将来使用超时语义将允许您将服务器行为链接到服务器SLA,例如#GetFutureSponse(SLA#u timeout_ms)。

如果您想深入了解线程(或进程或系统)之间的通信,这是一本书的技巧:

在线程之间共享对象引用很容易,但是您是否也需要在线程之间发送信号?例如,让一个向另一个指示“请处理此对象”,然后指示“确定,处理完成,请处理返回值”。为什么要命名变量回调?难道其他线程或其他东西不更有意义吗?(这毕竟不是一个函数)是的,这也是个好主意。我刚刚调用了它
callback
,因为我想表明这是thread1调用的东西。但实际上,这是一个简单的解决方案,它表明如果可以传递线程,那么就可以做任何事情。您还可以“同步”setter/getter。+1-这是我对共享对象集合的引用的一个很好的扩展,肯定会完成这项工作。
共享数组
您可能知道这一点,但由于阅读时不太清楚,给其他人一个警告:Volatile数组不等于Volatile数组元素,因此基本上需要不安全的代码——最好使用高级数据结构。
MyFirstThread extends Thread{
 public void setData(Object o){...}
}
MySecondThread extends Thread{
   MyFirstThread callback;
   MySecondThread(MyFirstThread callback){this.callback=callback)
}
MyFirstThread t1 = new MyFirstThread();
MySecondThread t2 = new MySecondThread(t1);    
t1.start();
t2.start();