能不能让线程池中的任务按策略顺序执行?

时间:2021-12-09 21:54:41
业务是这样的  , 有多个客户端通过Socket端连接到服务器, 然后不停的向服务器发送数据,

我想用消费者模型, 把这些数据都压入一个队列中取,然后用线程池用处理数据, 但是现在有一个问题不同客户端的数据是虽然没有关联,但是同一个客户端的数据是有顺序的,在处理好上一个数据前,不能用后面的数据,   用线程池就不能保证顺序执行, 直接在Socket线程中运行,又怕堵塞下一个数据,接到数据后new一个线程来执行又要频繁的开关线程, 如果为每一个Socket创建一个独立的线程来处理数据, 又会减少进程的可用线程?
请教一下,这种情况下怎样利用多线程?

15 个解决方案

#1


如果业务上不需要立刻处理,而是异步处理就成,那么通常把任务保存到数据库中,然后用一个独立的“windows任务计划程序”执行一个console程序进程去处理这些异步任务就行了。在这个console进程中,你使用一个线程,或者多个线程,那是你自己的“体验”的事情。关键是这类架构——根本不需要在当前进程里处理。

#2


引用 1 楼 sp1234 的回复:
如果业务上不需要立刻处理,而是异步处理就成,那么通常把任务保存到数据库中,然后用一个独立的“windows任务计划程序”执行一个console程序进程去处理这些异步任务就行了。在这个console进程中,你使用一个线程,或者多个线程,那是你自己的“体验”的事情。关键是这类架构——根本不需要在当前进程里处理。

请恕我愚钝, 我感觉这样只是把Socket的线程压力,放到了console进程中了,这个进程依然面临着怎么最大效率利用多线程的问题啊?

#3


引用 1 楼 sp1234 的回复:
如果业务上不需要立刻处理,而是异步处理就成,那么通常把任务保存到数据库中,然后用一个独立的“windows任务计划程序”执行一个console程序进程去处理这些异步任务就行了。在这个console进程中,你使用一个线程,或者多个线程,那是你自己的“体验”的事情。关键是这类架构——根本不需要在当前进程里处理。


另外我可能有些地方没有表达清楚,  有部分数据需要处理后返回给终端的, 虽然可以不"立即"返回处理结果才会有后面的数据,但是也不能让客户端等待太久

#4


引用 1 楼 sp1234 的回复:
如果业务上不需要立刻处理,而是异步处理就成,那么通常把任务保存到数据库中,然后用一个独立的“windows任务计划程序”执行一个console程序进程去处理这些异步任务就行了。在这个console进程中,你使用一个线程,或者多个线程,那是你自己的“体验”的事情。关键是这类架构——根本不需要在当前进程里处理。


我想了一个这么方法 不知道可行不可行,  为每一个客户端创建一个Queue, 然后线程池中的一个线程处理一个Queue

#5


引用 4 楼 ayun00 的回复:
Quote: 引用 1 楼 sp1234 的回复:

如果业务上不需要立刻处理,而是异步处理就成,那么通常把任务保存到数据库中,然后用一个独立的“windows任务计划程序”执行一个console程序进程去处理这些异步任务就行了。在这个console进程中,你使用一个线程,或者多个线程,那是你自己的“体验”的事情。关键是这类架构——根本不需要在当前进程里处理。


我想了一个这么方法 不知道可行不可行,  为每一个客户端创建一个Queue, 然后线程池中的一个线程处理一个Queue

可行。

若是客户数不太多,都不需要线程池,直接每个客户分配一个线程就行。

#6


引用 5 楼 rtdb 的回复:
Quote: 引用 4 楼 ayun00 的回复:

Quote: 引用 1 楼 sp1234 的回复:

如果业务上不需要立刻处理,而是异步处理就成,那么通常把任务保存到数据库中,然后用一个独立的“windows任务计划程序”执行一个console程序进程去处理这些异步任务就行了。在这个console进程中,你使用一个线程,或者多个线程,那是你自己的“体验”的事情。关键是这类架构——根本不需要在当前进程里处理。


我想了一个这么方法 不知道可行不可行,  为每一个客户端创建一个Queue, 然后线程池中的一个线程处理一个Queue

可行。

若是客户数不太多,都不需要线程池,直接每个客户分配一个线程就行。


现在就是客户数太多了 , 想节约线程

#7


有人吗? 能不能让线程池中的任务按策略顺序执行?

#8


完成接口.....

#9


可以参考一下unix的IPC通信中,对消息队列的处理方式,或者参考oracle中队列的处理方式
我觉得问题不在于是否使用线程方面着方面,在于你是否有必要定义一个全局有效的数据存储对象类,能够支持数据存取的原子性
以及针对具体的客户端(标记为ID)的有序性

#10


完全没能理解这是什么方案

你是说,客户端需要计算的数据,并不是一次性发到服务端,而是"一点一点的"发过来的吗
那就前一步处理完成之前,不要让客户端把后面的发过来,前面的处理完了,再发过来

如果客户端的数据是一次性发过来的,那么把对这些数据的处理放到同一个线程里执行(放到队列的同一项里去),而不是把同一个任务给分开

#11


着就好比雇了几个清洁工打扫房间
打扫顺序必须先扫上面,再扫下面,否则下面先扫了,再扫上面,灰又都落地上了,白扫了

要么你就让每个人都先打扫上面,谁打扫完了,再给他分配其他任务
要么就每个人负责一个房间,一开始就告诉他们打扫顺序

你把扫天棚,扫地,擦玻璃的任务都分开一股脑的给所有人,让他们自己去干,还有不乱的?

#12


我没有太想仔细看你关于“线程”的问题,因为你的问题很乱而且没有深入到真正的流程设计。所以我觉得你可以先搞懂一些非常简单的逻辑设计原则,而与线程无关的(!),将来你在去考虑“线程”这个词儿,会更好。

把一个任务分解为多个可以异步执行的任务,这时需要自己的设计能力的,这样才能先去有信心地知道分解之后的异步并发算法能够完成以前的同步顺序算法的相同的结果。

然后,你可以先把任务放到一些“傻瓜式”的存储中,例如内存数据库,甚至在不同机器上的分数据库中。而不要纠结什么“单进程、单数据库、单内存、单机”的东西。

再然后,从“第一个服务程序”去通知其它程序去“领取任务”,这可能是一个比较重要的设计机制。因为这可以保证效率和资源。因为不需要其他程序去轮询,而是第一个服务器程序去通知其它多个程序去领取任务、每一个子程序去评估任务、然后第一个服务程序才真正把任务交给某一个最终的子程序。

最后,你再来回到你的所谓“线程、任务、同步、算法”这些词儿上来,你的问题就能够“落地了”。

#13


线程只是一个非常简单的技术概念,它解决不了你的复杂业务设计上的缺失。特别是当你设计业务流程时连程序代码能不能在很小的一个范围(只有几条语句)上执行 lock 也不清楚,而这个时候你又提出了比较高大上的需求,这时候跟你说了线程同步的机制反而是会让你做出来的东西更容易“死锁”的。

最好的情况,是你先在简单问题上做技术研究。而把复杂的业务问题,用笨办法去解决。等以后你把笨办法的程序跑起来一段时间之后,再讨论设计重构问题。

#14


就你的问题来看,你可能提的问题超级简单(以至于我们根本无法理解你提的简单问题),也可能是确实有你想描述某种高性能的复杂一点的商业流程在里边(而你想尽量用最少的技术名词儿来描述你的纠结)。具体是太简单,还是你没有描述到“可落地的”业务流程,这还不太看得出来。我上面是按照后者,给你一些关于“先不要考虑线程,先把基本的并发流程设计出来”的建议。

如果是前者,那么这种回复就很简单了。正如 #10 楼所说,客户端没有得到前一个的回复就在上一个命令的同时提前发另外一个命令,服务器又不是专门为某个客户端独占的服务器,所以原本就不应该给它提供什么“数据是有顺序的”的服务。而要搞懂这个问题,随便拿一张白纸,你画一下两个对象(两个进程)之间的时序流程图,看看你头脑中关于“同时发送数据”跟“先后发送数据”的时序图有没有差别就行了。画好这种图,还是先不要纠结“线程”概念,先用跟线程无关的编程方法把并发(多进程)流程设计练习一下。

#15


该回复于2015-03-13 16:10:16被管理员删除

#1


如果业务上不需要立刻处理,而是异步处理就成,那么通常把任务保存到数据库中,然后用一个独立的“windows任务计划程序”执行一个console程序进程去处理这些异步任务就行了。在这个console进程中,你使用一个线程,或者多个线程,那是你自己的“体验”的事情。关键是这类架构——根本不需要在当前进程里处理。

#2


引用 1 楼 sp1234 的回复:
如果业务上不需要立刻处理,而是异步处理就成,那么通常把任务保存到数据库中,然后用一个独立的“windows任务计划程序”执行一个console程序进程去处理这些异步任务就行了。在这个console进程中,你使用一个线程,或者多个线程,那是你自己的“体验”的事情。关键是这类架构——根本不需要在当前进程里处理。

请恕我愚钝, 我感觉这样只是把Socket的线程压力,放到了console进程中了,这个进程依然面临着怎么最大效率利用多线程的问题啊?

#3


引用 1 楼 sp1234 的回复:
如果业务上不需要立刻处理,而是异步处理就成,那么通常把任务保存到数据库中,然后用一个独立的“windows任务计划程序”执行一个console程序进程去处理这些异步任务就行了。在这个console进程中,你使用一个线程,或者多个线程,那是你自己的“体验”的事情。关键是这类架构——根本不需要在当前进程里处理。


另外我可能有些地方没有表达清楚,  有部分数据需要处理后返回给终端的, 虽然可以不"立即"返回处理结果才会有后面的数据,但是也不能让客户端等待太久

#4


引用 1 楼 sp1234 的回复:
如果业务上不需要立刻处理,而是异步处理就成,那么通常把任务保存到数据库中,然后用一个独立的“windows任务计划程序”执行一个console程序进程去处理这些异步任务就行了。在这个console进程中,你使用一个线程,或者多个线程,那是你自己的“体验”的事情。关键是这类架构——根本不需要在当前进程里处理。


我想了一个这么方法 不知道可行不可行,  为每一个客户端创建一个Queue, 然后线程池中的一个线程处理一个Queue

#5


引用 4 楼 ayun00 的回复:
Quote: 引用 1 楼 sp1234 的回复:

如果业务上不需要立刻处理,而是异步处理就成,那么通常把任务保存到数据库中,然后用一个独立的“windows任务计划程序”执行一个console程序进程去处理这些异步任务就行了。在这个console进程中,你使用一个线程,或者多个线程,那是你自己的“体验”的事情。关键是这类架构——根本不需要在当前进程里处理。


我想了一个这么方法 不知道可行不可行,  为每一个客户端创建一个Queue, 然后线程池中的一个线程处理一个Queue

可行。

若是客户数不太多,都不需要线程池,直接每个客户分配一个线程就行。

#6


引用 5 楼 rtdb 的回复:
Quote: 引用 4 楼 ayun00 的回复:

Quote: 引用 1 楼 sp1234 的回复:

如果业务上不需要立刻处理,而是异步处理就成,那么通常把任务保存到数据库中,然后用一个独立的“windows任务计划程序”执行一个console程序进程去处理这些异步任务就行了。在这个console进程中,你使用一个线程,或者多个线程,那是你自己的“体验”的事情。关键是这类架构——根本不需要在当前进程里处理。


我想了一个这么方法 不知道可行不可行,  为每一个客户端创建一个Queue, 然后线程池中的一个线程处理一个Queue

可行。

若是客户数不太多,都不需要线程池,直接每个客户分配一个线程就行。


现在就是客户数太多了 , 想节约线程

#7


有人吗? 能不能让线程池中的任务按策略顺序执行?

#8


完成接口.....

#9


可以参考一下unix的IPC通信中,对消息队列的处理方式,或者参考oracle中队列的处理方式
我觉得问题不在于是否使用线程方面着方面,在于你是否有必要定义一个全局有效的数据存储对象类,能够支持数据存取的原子性
以及针对具体的客户端(标记为ID)的有序性

#10


完全没能理解这是什么方案

你是说,客户端需要计算的数据,并不是一次性发到服务端,而是"一点一点的"发过来的吗
那就前一步处理完成之前,不要让客户端把后面的发过来,前面的处理完了,再发过来

如果客户端的数据是一次性发过来的,那么把对这些数据的处理放到同一个线程里执行(放到队列的同一项里去),而不是把同一个任务给分开

#11


着就好比雇了几个清洁工打扫房间
打扫顺序必须先扫上面,再扫下面,否则下面先扫了,再扫上面,灰又都落地上了,白扫了

要么你就让每个人都先打扫上面,谁打扫完了,再给他分配其他任务
要么就每个人负责一个房间,一开始就告诉他们打扫顺序

你把扫天棚,扫地,擦玻璃的任务都分开一股脑的给所有人,让他们自己去干,还有不乱的?

#12


我没有太想仔细看你关于“线程”的问题,因为你的问题很乱而且没有深入到真正的流程设计。所以我觉得你可以先搞懂一些非常简单的逻辑设计原则,而与线程无关的(!),将来你在去考虑“线程”这个词儿,会更好。

把一个任务分解为多个可以异步执行的任务,这时需要自己的设计能力的,这样才能先去有信心地知道分解之后的异步并发算法能够完成以前的同步顺序算法的相同的结果。

然后,你可以先把任务放到一些“傻瓜式”的存储中,例如内存数据库,甚至在不同机器上的分数据库中。而不要纠结什么“单进程、单数据库、单内存、单机”的东西。

再然后,从“第一个服务程序”去通知其它程序去“领取任务”,这可能是一个比较重要的设计机制。因为这可以保证效率和资源。因为不需要其他程序去轮询,而是第一个服务器程序去通知其它多个程序去领取任务、每一个子程序去评估任务、然后第一个服务程序才真正把任务交给某一个最终的子程序。

最后,你再来回到你的所谓“线程、任务、同步、算法”这些词儿上来,你的问题就能够“落地了”。

#13


线程只是一个非常简单的技术概念,它解决不了你的复杂业务设计上的缺失。特别是当你设计业务流程时连程序代码能不能在很小的一个范围(只有几条语句)上执行 lock 也不清楚,而这个时候你又提出了比较高大上的需求,这时候跟你说了线程同步的机制反而是会让你做出来的东西更容易“死锁”的。

最好的情况,是你先在简单问题上做技术研究。而把复杂的业务问题,用笨办法去解决。等以后你把笨办法的程序跑起来一段时间之后,再讨论设计重构问题。

#14


就你的问题来看,你可能提的问题超级简单(以至于我们根本无法理解你提的简单问题),也可能是确实有你想描述某种高性能的复杂一点的商业流程在里边(而你想尽量用最少的技术名词儿来描述你的纠结)。具体是太简单,还是你没有描述到“可落地的”业务流程,这还不太看得出来。我上面是按照后者,给你一些关于“先不要考虑线程,先把基本的并发流程设计出来”的建议。

如果是前者,那么这种回复就很简单了。正如 #10 楼所说,客户端没有得到前一个的回复就在上一个命令的同时提前发另外一个命令,服务器又不是专门为某个客户端独占的服务器,所以原本就不应该给它提供什么“数据是有顺序的”的服务。而要搞懂这个问题,随便拿一张白纸,你画一下两个对象(两个进程)之间的时序流程图,看看你头脑中关于“同时发送数据”跟“先后发送数据”的时序图有没有差别就行了。画好这种图,还是先不要纠结“线程”概念,先用跟线程无关的编程方法把并发(多进程)流程设计练习一下。

#15


该回复于2015-03-13 16:10:16被管理员删除