解决方案 »

  1.   

    感觉你的意思是不需要BlockingQueue这个功能,只要最小数,最大数,超时时间三个就行了。而且你的意思是假如最大数为10,现在进去10个死循环的线程,执行这10个。再来5个,等待,如果超过设置的超时时间,那么这5个会被关掉对吗。
    也就是已经执行线程的时间没有管理,多长都行?
      

  2.   

    队列是放线程池当前没有空闲的线程来执行的任务,当有线程执行完的时候,队列中等待的线程就可以执行了,如果没有队列,线程池满了怎么办。第3条,我写的很清楚,是空闲线程空闲多长时间退出,线程池不用去管这个Runnable到底运行了多久,可能要执行1毫秒、也可能执行1小时,反正就是来任务了就执行,没有空闲线程就放到队列等待可能没描述好,和你理解的相反
      

  3.   

    重载下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);
        }
      

  4.   

    上面打错字了,把“改成” -> "改写"--------ps
    居然不能编辑自己的贴子,csdn做得真有毛病
      

  5.   


    是要继承ThreadPoolExecutor,重载execute方法,不过原来的execute里使用的方法变量都是私有的,还是自己把ThreadPoolExecutor里面的代码全搬过来,在改一下execute方法方便,就当自己实现了一个ExecutorService不过要改execute还要去深入研究一下BlockingQueue接口,实在没好方案了就这么办
      

  6.   

    c3p0 连接池 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    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>
      

  7.   

    我用tomcat自带的jdbc连接池,省时省力省心,我问的也不连接池,线程池方面有木有什么好的建议么
      

  8.   

    有第三方解决方案 backport-util-concurrent.jar
      

  9.   

    卤煮要的是线程池,有人给的数据库连接池
    推荐卤煮spring提供的线程池方案,在配置文件里配置成一个bean就可以了。
    <bean id ="taskExecutor"  class ="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >  
      

  10.   

    <bean id ="taskExecutor"  class ="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >  试过之后就是它了 ,楼主可以试试
      

  11.   

    有点高级了,还要配置文件,像3楼的方法,自己造个轮子估计更好用,没用过spring,用的话还要去学习一下,还是可以参考一下
      

  12.   

    其实我现在代码里还一堆new Thread(Runnable).start(),听人说这样不好,就折腾起线程池了大牛们是用什么样的线程池啊,分享一下呗,让小白升点经验
      

  13.   

    刚才又阅读了一下ThreadPoolExecutor源码,发现allowCoreThreadTimeOut方法可以设置核心线程空闲超时后关闭。
    因此可以把ThreadPoolExecutor的corePoolSize当作maximumPoolSize来用,设成一样大的值,这个效果和需要保持的线程数量为0的时候完全一样。
    满足了我的那个例子:但需要保持的线程数量不为0,看样子不改动ThreadPoolExecutor源码是做不到的,我改源码也测试实现了,只简单改动了两个地方。而我现在需要的就是例子那样的效果,ThreadPoolExecutor可以满足当前需求,折腾了这么久还是回到了原点
      

  14.   

    我用tomcat自带的jdbc连接池,省时省力省心,我问的也不连接池,线程池方面有木有什么好的建议么
    这个还不错 hibernate 版本带有这个
    性能等还行
      

  15.   

    想要创建一个公共的线程池,用来执行应用里的所有新开线程。
    希望能实现:
    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不提供这种功能有什么很好的理由吗