重载下ThreadPoolExecutor,改成它的execute方法,看下面方法里的注释,把#2和#3的逻辑换个位置就行了public void execute(Runnable command) { if (command == null) throw new NullPointerException(); /* * Proceed in 3 steps: * * 1. If fewer than corePoolSize threads are running, try to * start a new thread with the given command as its first * task. The call to addWorker atomically checks runState and * workerCount, and so prevents false alarms that would add * threads when it shouldn't, by returning false. * * 2. If a task can be successfully queued, then we still need * to double-check whether we should have added a thread * (because existing ones died since last checking) or that * the pool shut down since entry into this method. So we * recheck state and if necessary roll back the enqueuing if * stopped, or start a new thread if there are none. * * 3. If we cannot queue task, then we try to add a new * thread. If it fails, we know we are shut down or saturated * and so reject the task. */ int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } else if (!addWorker(command, false)) reject(command); }
卤煮要的是线程池,有人给的数据库连接池 推荐卤煮spring提供的线程池方案,在配置文件里配置成一个bean就可以了。 <bean id ="taskExecutor" class ="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >
<bean id ="taskExecutor" class ="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" > 试过之后就是它了 ,楼主可以试试
也就是已经执行线程的时间没有管理,多长都行?
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
居然不能编辑自己的贴子,csdn做得真有毛病
是要继承ThreadPoolExecutor,重载execute方法,不过原来的execute里使用的方法变量都是私有的,还是自己把ThreadPoolExecutor里面的代码全搬过来,在改一下execute方法方便,就当自己实现了一个ExecutorService不过要改execute还要去深入研究一下BlockingQueue接口,实在没好方案了就这么办
destroy-method="close">
<property name="driverClass" value="" />
<property name="jdbcUrl" value="" />
<property name="user" value="" />
<property name="password" value="" /> <!--连接池中保留的最小连接数。 -->
<property name="minPoolSize" value="3" /> <!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="50" /> <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="3" /> <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="60" /> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="3" /> <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0 -->
<property name="maxStatements" value="0" /> <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="60" /> <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts" value="30" /> <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
获取连接失败后该数据源将申明已断开并永久关闭。Default: false -->
<property name="breakAfterAcquireFailure" value="true" /> <!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
等方法来提升连接测试的性能。Default: false -->
<property name="testConnectionOnCheckout" value="false" /> <property name="preferredTestQuery" value="select 1" />
</bean>
推荐卤煮spring提供的线程池方案,在配置文件里配置成一个bean就可以了。
<bean id ="taskExecutor" class ="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >
因此可以把ThreadPoolExecutor的corePoolSize当作maximumPoolSize来用,设成一样大的值,这个效果和需要保持的线程数量为0的时候完全一样。
满足了我的那个例子:但需要保持的线程数量不为0,看样子不改动ThreadPoolExecutor源码是做不到的,我改源码也测试实现了,只简单改动了两个地方。而我现在需要的就是例子那样的效果,ThreadPoolExecutor可以满足当前需求,折腾了这么久还是回到了原点
这个还不错 hibernate 版本带有这个
性能等还行
希望能实现:
1、corePoolSize:线程池中保持一定数量的线程,不会因为空闲超时关闭
2、maximumPoolSize:线程池中有最大线程限制,只要不超过限制,新线程总会立即执行,线程池满时新线程请求放到队列中等待
3、keepAliveTime:当前线程池中的线程数量超过corePoolSize,多余的线程空闲线程超过这个时间自动关闭比如设置corePoolSize=0、maximumPoolSize=10、keepAliveTime=1000ms,线程池创建好后,来了15个任务,线程池中的线程数量为10,队列中等待的线程数量为5,全部执行完成后,1秒内没收到任何任务,线程全部空闲超时,线程池中的线程为0。
很像jdbc的连接池功能。ThreadPoolExecutor如果这样设置:
ThreadPoolExecutor(0, 10, 1, TimeUnit.SECONDS, BlockingQueue),也同时来15个线程,根据BlockingQueue不同,要么只有一个线程串行执行,要么满了10个线程后面的5个线程被抛弃,完全不符合要求
搞不明白ThreadPoolExecutor为什么要等队列满了才去创建corePoolSize以外的线程,maximumPoolSize在无界队列中成了摆设,刚刚接触线程池这种高级货,为啥不搞一个和jdbc连接池一样的功能,ThreadPoolExecutor不提供这种功能有什么很好的理由吗