这个题目比较怪,听俺道来。俺一直在负责公司游戏服务器的开发和维护,日积月累下来终于将原本混乱的代码和结构重构的比较清晰了,在此过程中的体会就是,重构啊,不仅仅是技术活,更多是要克服不情愿的、得过且过的心理去做,去做了才发现麻烦并没有想象中的大。
改造过程中遇到这么个问题,我想将对某个创建的游戏的操作都固定在一个线程执行,与其他游戏可以并发地处理;或者说依据游戏id派发到某个固定的线程处
理,对此游戏的操作都是串行化。不是俺不想彻底并行化,但是要将现有的代码改造成适应并行化相当困难,俺尝试的结果是问题百出,因此就想了这么个折中策
略,不同游戏之间的操作可以并行,单个游戏内操作串行。怎么派发呢?很简单的机制,根据id%size结果来处理就好,size就是你准备开的线程数。因
此可以很容易地模拟一个生产者消费者模型的线程池,根据游戏id%size的结果将任务塞到队列中,让生产者线程顺序处理。已经有部分代码是这样处理的,
不过是自己实现的模型(BlockingQueue),比较不适合俺想要的任务式的处理过程,灵机一动,jdk5引入的线程池不是有个单线程的版本吗?俺
将这个线程池再做个池不就OK了?说起来不好理解,看代码:
<!---->public
interface
Task
extends
Runnable {
public
int
getCode();
}
嗯,定义一个Task接口,继承Runnable,多了个getCode方法用于决定派发任务到哪个ExecutorService执行。线程池池登场:
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThreadPoolPool {
private Map<Integer, ExecutorService> threadPoolMap = new HashMap<Integer, ExecutorService>();
private int size;
public SingleThreadPoolPool(int size) {
this.size = size;
for (int i = 0; i < size; i++) {
ExecutorService executor = Executors.newSingleThreadExecutor();
threadPoolMap.put(i, executor);
}
}
public void execute(Task task) {
if (task == null)
return;
threadPoolMap.get(getIndex(task.getCode())).execute(task);
}
public void execute(int code, Runnable r) {
if (r == null)
return;
threadPoolMap.get(getIndex(code)).execute(r);
}
private int getIndex(int code) {
int index = -1;
if (code < 0)
index = 0;
else
index = code % this.size;
return index;
}
public void shutdown() {
for (int i = 0; i < size; i++) {
threadPoolMap.get(i).shutdown();
}
threadPoolMap.clear();
}
public int size() {
return this.size;
}
}
哇靠,这也太简单了,这就能保证code相同的任务会被排队顺序执行。是啊,很简单,不是啥高科技,但简单明了地实现了俺的需求。需要注意的是,只有通过Executor的execute方法提交的任务才会被排到队列中哦。
分享到:
相关推荐
最简单高效的JAVA对象池、线程池、以及使用对象池技术实现的数据库连接池 已在生产运行5年以上的代码 若有任何问题请与我联系
这是一个很简单的实现啦对象池与线程池的融合,方法的主要参数,线程池大小、对象池大小、对象的创建工厂(继承接口自己实现),执行时传入方面名称即可。(invoke方法第一个为参数为方法名,第二是可变参数(及方法...
里面是我个人通过模板来实现的通用池,并在通用池的基础上开发的一个线程池和数据库池。由于水平有限,所以开发的池可能比较简单。经过个人验证,这些池都是可用的,如有问题,可加QQ:970757285.
采用线程池 连接池 数据库 采用mysql,listcontr控件 右键菜单 此程序仅供学习 功能 增删改查学生,基本上各种非法操作验证都加了
服务端使用线程池实现。服务端主线程负责接收用 客户端请求,将客户端请求词封装成任务,再用锁机制 将任务添加到线程池中的任务队列中。工作线程通过互 斥量和条件变量访问任务队列,实现线程同步,使得线 程池...
libstpool是一个轻便高效的跨平台 支持win32 linux unix arm 的c语言线程池 任务池库 支持优先级任务
在Linux 系统下面用C 语言实现的高并发服务器的代码,具体用到了Epoll,线程池,数据库连接池。 具体可以看下连接http://blog.csdn.net/wuyuxing24/article/details/48758927
作为五大池之一(内存池、连接池、线程池、进程池、协程池),线程池的应用非常广泛,不管是客户 端程序,还是后台服务程序,都是提高业务处理能力的必备模块。有很多开源的线程池实现,虽然各自 接口使用上稍有区别,...
在实际应用中,线程池常用于数据库连接池、网络请求处理、大量计算任务等场景,通过合理使用线程池,可以显著提升程序的并发性能和响应速度。 总之,C++线程池是多线程编程中的一个重要工具,理解和掌握其设计与...
线程池是多线程编程中的一个重要概念,它是一种线程使用模式,通过预先创建一组线程,并将它们组织成一个池,来处理到来的任务。在VC++中,线程池可以帮助开发者更有效地管理和调度线程,从而提高程序的并发性能和...
IOCP 内存池线程池的一个例子 主要优化在性能上 包括IO收发的重叠结构用了内存池技术
Linux 线程池 +连接池 ,备份学习。。。。。。。。。。。。。。。
在C#编程中,线程池(ThreadPool)是一种高效的线程管理机制,它允许开发者创建并管理多个线程,而无需直接操作线程对象。线程池中的线程可以复用,减少了创建和销毁线程的开销。当我们需要执行大量短生命周期的任务...
corePoolSize:核心池的大小,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中; ...
网上有现成的cthreadpool的代码,是c版的,且没有任务队列功能,不能做到任务的安全退出,根据实际需要写了一个c++版的,本程序实现了c++的封装,并实现了任务池和线程安全退出。弥补了c版的不足 在linux调试通过并...
关于SOCKET线程池,多个线程可否对同一个套接字同时写操作等问题?
在IT领域,线程池是一种优化资源管理的技术,它允许应用程序预先创建一组线程,并将它们维护在一个集合中,以供后续任务复用。MFC(Microsoft Foundation Classes)是微软提供的一个C++类库,用于简化Windows应用...
- 当线程池达到最大连接池数`maxPools`时,新任务可能会被阻塞,直到有线程完成任务并释放资源。 - 检查周期`checkThreadPeriod`可能用于判断是否需要调整线程池大小,例如减少空闲线程或增加线程以处理新任务。 ...
线程池是一种多线程处理形式,通过维护一组可重用线程来提高系统的效率。在操作系统和编程语言中,线程池的概念被广泛应用,因为它能够优化资源的使用,减少线程创建和销毁的开销,并能更好地控制系统的并发级别。 ...