简体   繁体   English

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

[英]Sending objects back and forth between threads in java?

I have multiple client handler threads, these threads need to pass received object to a server queue and the sever queue will pass another type of object back to the sending thread. 我有多个客户端处理程序线程,这些线程需要将接收到的对象传递给服务器队列,服务器队列将另一种类型的对象传递回发送线程。 The server queue is started and keeps running when the server starts.I am not sure which thread mechanism to use for the client handler threads notified an object is sent back. 服务器队列启动并在服务器启动时继续运行。我不确定通知哪个线程机制用于通知客户端处理程序线程的对象被发回。 I don't intend to use socket or writing to a file. 我不打算使用套接字或写入文件。

If you wanted to do actual message passing take a look at SynchronusQueue . 如果你想做实际的消息传递,请看看SynchronusQueue Each thread will have reference to the queue and would wait until one thread passed the reference through the queue. 每个线程都将引用该队列,并等待一个线程通过队列传递引用。

This would be thread safe and address your requirements. 这将是线程安全的,并满足您的要求。

Though if you are simply looking to have threads read and write a shared variable you can use normalocity's suggestion though it's thread-safety depends on how you access it (via sychronized or volatile) 虽然如果你只是想让线程读写一个共享变量,你可以使用normalocity的建议虽然它的线程安全取决于你如何访问它(通过sychronized或volatile)

As far as making objects accessible in Java, there's no difference between multi-thread and single-thread. 至于使用Java访问对象,多线程和单线程之间没有区别。 You just follow the scope rules (public, private, protected), and that's it. 您只需遵循范围规则(公共,私有,受保护),就是这样。 Multiple threads all run within the same process, so there isn't any special thread-only scope rules to know about. 多个线程都在同一进程中运行,因此没有任何特殊的线程范围规则可供了解。

For example, define a method where you pass the object in, and make that method accessible from the other thread. 例如,定义一个传入对象的方法,并使该方法可以从另一个线程访问。 The object you want to pass around simply needs to be accessible from the other thread's scope. 您想要传递的对象只需要从另一个线程的范围访问。

As far as thread-safety, you can synchronize your writes , and for the most part, that will take care of things. 就线程安全而言, 您可以同步写入 ,并且在大多数情况下,可以处理事务。 Thread safety can get a bit hairy the more complicated your code, but I think this will get you started. 线程安全可能会变得有点毛茸茸,代码越复杂,但我认为这会让你开始。

One method for processing objects, and producing result objects is to have a shared array or LinkedList that acts as a queue of objects, containing the objects to be processed, and the resulting objects from that processing. 处理对象和生成结果对象的一种方法是使用共享数组或LinkedList作为对象队列,包含要处理的对象以及来自该处理的结果对象。 It's hard to go into much more detail than that without more specifics on what exactly you're trying to do, but most shared access to objects between threads comes down to either inter-thread method calls, or some shared collection/queue of objects. 如果没有更具体的细节,你很难详细说明你正在尝试做什么,但大多数线程之间对象的共享访问都归结为线程间方法调用或对象的一些共享集合/队列。

Unless you are absolutely certain that it will always be only a single object at a time, use some sort of Queue. 除非您完全确定它一次只能是一个对象,否则请使用某种Queue。

If you are certain that it will always be only a single object at a time, use some sort of Queue anyway. 如果您确定它一次只能是一个对象,那么无论如何都要使用某种Queue。 :-) :-)

Just use simple dependency injection . 只需使用简单的依赖注入

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();

You can now do callback.setData(...) in your second thread. 您现在可以在第二个线程中执行callback.setData(...)

I find this to be the safest way. 我发现这是最安全的方式。 Other solutions involve using volatile or some kind of shared object which I think is an overkill. 其他解决方案涉及使用volatile或某种共享对象,我认为这是一种过度杀伤力。

You may also want to use BlockingQueue and pass both of those to each thread. 您可能还想使用BlockingQueue并将这两者传递给每个线程。 If you plan to have more than one thread then it is probably a better solution. 如果您计划拥有多个线程,那么它可能是更好的解决方案。

  • Use a concurrent queue from the java.util.concurrent.*. 使用java.util.concurrent。*中的并发队列。

why? 为什么? Almost guaranteed to provide better general performance than any thing hand rolled. 几乎可以保证提供比手动轧制的任何东西更好的一般性能。

recommendation: use a bound queue and you will get back-pressure for free. 建议:使用绑定队列,你将获得免费的背压。

note: the depth of queue determines your general latency characteristics: shallower queues will have lower latencies at the cost of reduced bandwidth. 注意:队列深度决定了您的一般延迟特性:较浅的队列将以较低的带宽为代价具有较低的延迟。

  • Use Future semantics 使用Future语义

why? 为什么? Futures provide a proven and standard means of getting asynchronous result. 期货提供了一种经过验证的标准方法来获得异步结果。

recommendation: create a simple Request class and expose a method #getFutureResponse(). 建议:创建一个简单的Request类并公开一个方法#getFutureResponse()。 The implementation of this method can use a variety of signaling strategies, such as Lock, flag (using Atomic/CAS), etc. 该方法的实现可以使用各种信令策略,例如Lock,flag(使用Atomic / CAS)等。

note: use of timeout semantics in Future will allow you to link server behavior to your server SLA eg #getFutureResponse(sla_timeout_ms). 注意:在Future中使用超时语义将允许您将服务器行为链接到服务器SLA,例如#getFutureResponse(sla_timeout_ms)。

如果您想更深入地了解线程(或进程或系统)之间的通信,可以获得一本书的小贴士: 面向模式的软件架构第2卷:并发和联网对象的模式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM