简体   繁体   English

多线程与单线程

[英]Multiple threads vs single thread

I am working on a server client application right now (just for learning purposes), and am trying to get information to make a design decision regarding threads in this application. 我现在正在研究服务器客户端应用程序(仅出于学习目的),并试图获取信息以做出有关此应用程序中线程的设计决策。

Currently i have one thread in charge of all nonblocking io with the clients. 目前,我有一个线程负责与客户端的所有非阻塞io。 When it receives any data, it sends it off to a worker thread that creates an "instruction set" out of those bytes, then acts on it accordingly. 当它接收到任何数据时,会将其发送到工作线程,该工作线程从这些字节中创建一个“指令集”,然后对其进行相应的操作。 However, according to the instruction set it could act on any number of hundreds of objects (each object will cap out somewhere between 2 and 12 clients that can interact with it). 但是,根据指令集,它可以作用于任意数量的数百个对象(每个对象将限制2到12个可以与之交互的客户端之间的位置)。 I am trying to figure out if I should handle all of the instruction sets on that same thread, and just block while i handle each set, or if i should create separate threads for each object, and then pass each received instruction set off to the given objects thread for handling. 我试图弄清楚是否应该在同一线程上处理所有指令集,并在处理每个指令集时阻塞,或者是否应该为每个对象创建单独的线程,然后将每个接收到的指令集传递给给定对象线程进行处理。

My question boils down to at what point (if any) is having more inactive threads that are waiting for data slow down the system compared to having one worker thread that handles all the data (and blocks while it is handling each instruction set). 我的问题归结为,与只有一个工作线程处理所有数据(并在处理每个指令集时阻塞)相比,到什么时候(如果有)正在等待数据的非活动线程会使系统变慢。

If i created a separate thread for each object, then i am thinking it could increase concurrency as once it the main worker thread creates an instruction set, it can just pass it off to be handled and imeditally start working on the next instruction set. 如果我为每个对象创建一个单独的线程,那么我认为它可以增加并发性,因为一旦主工作线程创建了一个指令集,它就可以将其传递出去进行处理,并立即开始处理下一个指令集。

However, i keep hearing about how creating and managing threads has an underlying cost to it, because the OS has to manage them. 但是,我不断听到有关创建和管理线程的基本成本,因为操作系统必须对其进行管理。 So if i created a thread for an object that could have at most 2 clients able to interact with it, would the underlying cost of managing it negate the concurrent benefit of it, sense only 2 clients could utilize that concurrency? 因此,如果我为一个对象创建了一个线程,该线程最多可以有2个客户端能够与其交互,那么管理该线程的基本成本是否会抵消它的并发优势,是否只有2个客户端可以利用该并发性?

As always, any advice/articles are greatly appreciated :) 与往常一样,任何建议/文章都将不胜感激:)

I'd recommend following the example set by Java EE app servers. 我建议遵循Java EE应用服务器设置的示例。

Have a queue for incoming requests and a pool for handler threads. 有一个用于传入请求的队列和一个用于处理程序线程的池。 When a request comes in, have the controller get a handler thread out of the pool, take the request off the queue, and give it to the handler thread to process. 当请求进入时,让控制器从池中获取处理程序线程,将请求移出队列,然后将其交给处理程序线程进行处理。 When the thread is done, put it back into the pool. 线程完成后,将其放回池中。

If the number of requests is greater than the number of handler threads, the queue lets them accumulate and wait until a thread becomes available. 如果请求的数量大于处理程序线程的数量,则队列让它们积累并等待直到线程可用。

This design gives you two benefits: 此设计为您带来两个好处:

  1. It lets you set the size of the handler thread pool and match it to your server resources 它使您可以设置处理程序线程池的大小并将其与服务器资源匹配
  2. It throttles the incoming requests when they exceed the pool capacity so you aren't blocking and waiting or losing requests. 当传入的请求超过池容量时,它会限制传入的请求,因此您不会阻塞,等待或丢失请求。

Concurrency is your friend here. 并发是您的朋友。 It'll help keep your server scalable. 这将有助于保持服务器的可扩展性。

If the threads are actually sleeping, the overhead cost should be nothing more that what it costs to start them in the first place. 如果线程实际上处于睡眠状态,则开销成本仅应与启动它们所需的开销无异。 Sleeping threads have a fairly efficient method of staying asleep until they are needed: waiting for an interrupt. 睡眠线程具有一种相当有效的保持睡眠状态的方法,直到需要它们时:等待中断。 (note a common method of sleeping is to wake after an interrupt from the clock, which is how you can specify the amount of time it should sleep). (请注意,一种常见的睡眠方法是在时钟中断后唤醒,这是您可以指定睡眠时间的方式)。 If those threads are not taking advantage of the hardware because they are waking up off of something like a timer instead of something more specific to your program, the overhead could be astronomical with all of the context switches the processor would be forced to make, most notably emptying the cache. 如果这些线程没有利用硬件,因为它们从定时器之类的东西中唤醒,而不是从程序中更具体的东西中唤醒,那么开销将是天文数字,因为处理器将不得不进行所有上下文切换,大多数尤其是清空缓存。

Test it each way. 每种方式进行测试。 You have to block sometimes, you can't just ram everything through unless you are sure of your computing power. 有时您必须阻止,除非您确定自己的计算能力,否则不能仅将所有内容都弄光。 The slower/less capable the machines the more blocking is going to be nessesary. 机器越慢/能力越弱,需要的阻塞就越大。 Design your application to be adjustable to the situation. 将您的应用程序设计为可根据情况进行调整。 Better yet let it keep track of what is going on and let it adjust itself. 更好的是,让它跟踪正在发生的事情,并自行调整。

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

相关问题 使用Runnable VS的单个实例创建多个线程。 每个线程都有单独的实例 - Creating multiple threads with a single instance of Runnable VS. with separate instances for each thread 使用本机接口的多个java线程与用于多线程本机的单个java线程 - Multiple java threads using native interface vs single java thread for multi threaded native 将数据从多个线程发送到单个线程 - Send Data from multiple threads to a single thread Java:在单个线程中修改对象,在多个线程中读取 - Java: modifying object in a single thread, reading in multiple threads 如何将多个内核/线程组合成一个线程? - How can multiple cores/threads be combined into a single thread? 从单个线程修改哈希映射并从多个线程读取? - Modifying hash map from a single thread and reading from multiple threads? 如何在Java中同步一组多个线程相对于单个线程 - how to synchronize a set of multiple threads with respect to a single thread in Java HashMap resize() 同时单线程写多线程读 - HashMap resize() while single thread writing and multiple threads reading Java:监听具有更多线程的单个端口而不是监听多个端口 - Java: listening to a single port with more threads vs listening to multiple ports 线程可运行 vs 扩展线程 - threads runnable vs extends thread
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM