简体   繁体   English

Java Thread用于管理套接字和运行类方法

[英]Java Thread to manage socket and run class method

I have a Java thread that I start so it keeps listening to a socket (considering the a socket read is blocking a thread is needed). 我有一个Java线程,我开始,所以它一直在监听一个套接字(考虑到一个套接字读取阻塞一个线程是必要的)。

After the Thread receives the data from the socket it needs to call a method from a class. 在线程从套接字接收数据后,它需要从类中调用方法。

Now I have two options to do this: 现在我有两个选项可以做到这一点:

Declare an interface that is passed to the Thread and implemented in a class. 声明一个传递给Thread并在类中实现的接口。 When the thread calls the interface method the implementing classes will run it. 当线程调用接口方法时,实现类将运行它。

Or I can pass the class instance to the Thread as a parameter and then call the class method. 或者我可以将类实例作为参数传递给Thread,然后调用类方法。

But I wanted to know if the thread blocks while the method is running. 但我想知道在方法运行时线程是否阻塞。

I suppose so but I'm not sure. 我想是的,但我不确定。

I wanted the thread to have a Socket event behavior. 我希望该线程具有Socket事件行为。 What I mean is to only be responsible for reading the data from the socket and fire functions in the main Class, the one that called the Thread. 我的意思是只负责读取主类中的套接字和触发函数中的数据,即调用线程的类。

Yes, the thread will block while executing the method, so it can not read from the socket at the same time. 是的,线程将在执行方法时阻塞,因此它无法同时从套接字读取。 No information will be lost, the transfer only takes longer and you can get a socket timeout if the computation takes too long. 不会丢失任何信息,传输只需要更长的时间,如果计算时间过长,您可以获得套接字超时。

If your method takes much time to run, you should execute it in another worker thread. 如果您的方法需要很长时间才能运行,那么您应该在另一个工作线程中执行它。 I recommend to use an Executor for that. 我建议使用Executor

You have various options : 你有各种选择:

  • Make your class a child class of Thread (easier code but you'll merge functionnal part - your main code - with a technical aspect (extending the Thread)) 使您的类成为Thread的子类(更简单的代码,但您将合并函数部分 - 您的主要代码 - 与技术方面(扩展Thread))
  • Make your class implements the Runnable interface and start a new thread with that Runnable (i often do like that). 让你的类实现Runnable接口并使用Runnable启动一个新线程(我经常这样做)。 So your main code still remains in a overriden run method, but the inheritance tree is up to you (your main class can extend one of your other class) 所以你的主代码仍然保留在重写的run方法中,但是继承树取决于你(你的主类可以扩展你的另一个类)
  • Keep separated your main code / the thread with two classes (one for your main code, one for the thread), linking the two at your will (remember that if you make an inner thread inside another class, the inner thread can use any final properties, for example). 保持主要代码/线程分开两个类(一个用于主代码,一个用于线程),根据您的意愿链接两个类(请记住,如果您在另一个类中创建内部线程,内部线程可以使用任何最终属性,例如)。

As stated in other answers, anything happening in your run() method is of course blocking the execution. 如其他答案所述,run()方法中发生的任何事情当然都会阻止执行。

As a sidenote, if you're going to deal with threads and sockets, i strongly suggest you to have a look at NIO frameworks like Netty that are just there for this kind of behavior : event driven client/server application through NewIO sockets. 作为旁注,如果您要处理线程和套接字,我强烈建议您查看像Netty这样的NIO框架,这些行为只是存在于这种行为中:事件驱动的客户端/服务器应用程序通过NewIO套接字。

As another sidenote, i often use this pattern : 作为另一个旁注,我经常使用这种模式:

  • start an acquisition thread that will catch the event ; 启动一个将捕获事件的获取线程;
  • push them in a linkedblockingqueue (queue.offer()) ; 将它们推入linkedblockingqueue(queue.offer());
  • have another thread that shares the same linkedblockingqueue (with queue.take()) : this operation is blocking, the threads will be blocked as long as the queue is empty ; 有另一个共享相同的linkedblockingqueue的线程(使用queue.take()):这个操作是阻塞的,只要队列为空,线程就会被阻塞;

This is a very simple way to have one thread as "producer", and one thread as "consumer". 这是一个非常简单的方法,将一个线程作为“生产者”,将一个线程作为“消费者”。 You can even have various consumers awaiting on the same queue. 您甚至可以让各种消费者在同一个队列中等待。

But I wanted to know if the thread blocks while the method is running 但我想知道在方法运行时线程是否阻塞

Yes it does block. 是的它确实阻止了。
If inside run you call a method to process something it doesn't matter if that is an interface etc as you ask it only matters what does the method actually do 如果在内部run你调用一个方法来处理一些东西,如果这是一个接口等并不重要,因为你问它只关系该方法实际上做了什么

In your case you have only 1 option. 在您的情况下,您只有一个选项。
Make sure that you return the control back to your socket listening thread asap. 确保尽快将控件返回到套接字监听线程。
This can happen by designing/mandating the processing class to handle the processing in a different thread. 这可以通过设计/强制处理类来处理不同线程中的处理来实现。
Actually your problem is not something new. 实际上你的问题并不是什么新鲜事。 In event based designs there is the requirement to process the event as fast as possible so as to not block the event queue based flow. 在基于事件的设计中,需要尽可能快地处理事件,以便不阻止基于事件队列的流。
And this is how I would recommend you to design arround. 这就是我建议你设计arround的方法。 Not use any interface to interact with the listening thread but register an event listener(s). 不使用任何接口与监听线程交互,而是注册事件监听器。

When an event occurs ie your listening thread reads data, it will pass the data as event to your listener(s) at which point of course it will block. 当一个事件发生时,即你的监听线程读取数据时,它会将数据作为事件传递给你的监听器,当然它将阻塞。
Then you should start a new thread to do the processing and the listening thread can continue with its work 然后你应该开始一个新线程来进行处理,监听线程可以继续它的工作

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

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