精华内容
下载资源
问答
  • Spring线程池

    2016-06-24 12:13:08
    最近研究了一下spring线程池技术。 起因就是看到同事遇到了并发相关的问题,所以跟着一起折腾这个问题。 下面是对于Spring线程池的研究记录 废话不说,直接上代码 在Spring中配置线程池 ...
    最近研究了一下spring线程池技术。
    起因就是看到同事遇到了并发相关的问题,所以跟着一起折腾这个问题。
    下面是对于Spring线程池的研究记录

    废话不说,直接上代码

    在Spring中配置线程池

    <!-- 配置线程池 -->  
    	<bean id ="threadPoolExecutor"  class ="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >  
    	    <!-- 线程池同时执行的线程数-->  
    		<property name ="corePoolSize" value ="10" />  
    	    <!-- 线程池维护线程所允许的空闲时间(超过corePoolSize数量的线程,不被销毁,保持其状态的时间) -->  
    		<property name ="keepAliveSeconds" value ="30000" />  
    	    <!-- 线程池维护线程的最大数量 -->  
    		<property name ="maxPoolSize" value ="20" />  
    	    <!-- 线程池所缓冲队列数 -->  
    		<property name ="queueCapacity" value ="2000" />  
    	</bean>  

    Contoller注入的部分代码

          <property name="taskExecutor" ref="taskExecutor"></property>
    </bean>

    Controller的部分代码

    <span style="white-space:pre">private ThreadPoolTaskExecutor taskExecutor;
    public String batchImportSRMProduct2Hybris(final String request) throws Exception {
    //添加线程到线程池
    		taskExecutor.execute(new TestRunable());
    		taskExecutor.execute(new TestRunable());
    		taskExecutor.execute(new TestRunable());
    		taskExecutor.execute(new TestRunable());
    		taskExecutor.execute(new TestRunable());
    		taskExecutor.execute(new TestRunable());
    		taskExecutor.execute(new TestRunable());
    		taskExecutor.execute(new TestRunable());
    		taskExecutor.execute(new TestRunable());
    //输出线程池的部分信息
                    final String info ="thread pool ActiveCount:"+taskExecutor.getActiveCount()
    				+",queue size:"+taskExecutor.getThreadPoolExecutor().getQueue().size()
    				+"Core Pool Size:"+taskExecutor.getCorePoolSize()
    				+"Max Pool Size:"+taskExecutor.getMaxPoolSize();
    		System.out.println(info);
    		return "1111";
    }
    
    public ThreadPoolTaskExecutor getTaskExecutor() {
    	return taskExecutor;
    }
    
    public void setTaskExecutor(final ThreadPoolTaskExecutor taskExecutor) {
    	this.taskExecutor = taskExecutor;
    }</span>
    /** 
     * 测试Runnable实现类
     *
     * @author sunyx 
     * @since JDK 1.8 
     */
    public class TestRunable implements Runnable {
    
    	@Override
    	public void run() {
    		for (int i = 0; i < 5; i++) {
    			System.out.println(Thread.currentThread().getName()+","+Thread.currentThread().getId()+"process:"+(i+1)+"/5");
    			try {
    				Thread.sleep(1000);
    			}
    			catch (final InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    		
    	}
    	
    }

    运行结果


    因为之前跑过一次单个的请求,所以多出了10个线程。

    200个请求,每个请求执行10个线程,无任何压力啊~~~~~


    展开全文
  • spring 线程池 线程池对于执行同步和异步过程非常重要。 本文介绍如何使用Spring开发和监视线程池服务。 创建线程池已通过两种替代方法进行了说明。 二手技术 : JDK 1.6.0_21 春天3.0.5 Maven的3.0.2 步骤1:...

    spring 线程池

    线程池对于执行同步和异步过程非常重要。 本文介绍如何使用Spring开发和监视线程池服务。 创建线程池已通过两种替代方法进行了说明。

    二手技术

    JDK 1.6.0_21
    春天3.0.5
    Maven的3.0.2

    步骤1:建立已完成的专案

    创建一个Maven项目,如下所示。 (可以使用Maven或IDE插件创建)。

    步骤2:图书馆

    Spring依赖项已添加到Maven的pom.xml中。

    <!-- Spring 3 dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>

    为了创建runnable-jar,可以使用以下插件。

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>1.3.1</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
                <configuration>
                    <transformers>
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>com.otv.exe.Application</mainClass>
                        </transformer>
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                            <resource>META-INF/spring.handlers</resource>
                        </transformer>
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                            <resource>META-INF/spring.schemas</resource>
                        </transformer>
                    </transformers>
                </configuration>
            </execution>
        </executions>
    </plugin>

    第3步:创建任务班

    通过实现Runnable接口可以创建一个新的TestTask类。 此类显示要执行的任务。

    package com.otv.task;
     
    import org.apache.log4j.Logger;
     
    /**
     * @author onlinetechvision.com
     * @since 17 Oct 2011
     * @version 1.0.0
     *
     */
    public class TestTask implements Runnable {
     
        private static Logger log = Logger.getLogger(TestTask.class);
        String taskName;
     
        public TestTask() {
        }
     
        public TestTask(String taskName) {
            this.taskName = taskName;
        }
     
        public void run() {
            try {
                log.debug(this.taskName + " : is started.");
                Thread.sleep(10000);
                log.debug(this.taskName + " : is completed.");
            } catch (InterruptedException e) {
                log.error(this.taskName + " : is not completed!");
                e.printStackTrace();
            }
        }
     
        @Override
        public String toString() {
            return (getTaskName());
        }
     
        public String getTaskName() {
            return taskName;
        }
     
        public void setTaskName(String taskName) {
            this.taskName = taskName;
        }
    }

    步骤4:建立TestRejectedExecutionHandler类别

    通过实现RejectedExecutionHandler接口创建TestRejectedExecutionHandler类。 如果没有空闲线程并且队列溢出,则将拒绝任务。 此类处理被拒绝的任务。

    package com.otv.handler;
     
    import java.util.concurrent.RejectedExecutionHandler;
    import java.util.concurrent.ThreadPoolExecutor;
     
    import org.apache.log4j.Logger;
     
    /**
     * @author onlinetechvision.com
     * @since 17 Oct 2011
     * @version 1.0.0
     *
     */
    public class TestRejectedExecutionHandler implements RejectedExecutionHandler {
     
        private static Logger log = Logger.getLogger(TestRejectedExecutionHandler.class);
     
        public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) {
            log.debug(runnable.toString() + " : has been rejected");
        }
    }

    步骤5:创建ITestThreadPoolExecutorService接口

    ITestThreadPoolExecutorService接口已创建。

    package com.otv.srv;
     
    import java.util.concurrent.ThreadPoolExecutor;
     
    import com.otv.handler.TestRejectedExecutionHandler;
     
    /**
     * @author onlinetechvision.com
     * @since 17 Oct 2011
     * @version 1.0.0
     *
     */
    public interface ITestThreadPoolExecutorService {
     
        public ThreadPoolExecutor createNewThreadPool();
     
        public int getCorePoolSize();
     
        public void setCorePoolSize(int corePoolSize);
     
        public int getMaxPoolSize();
     
        public void setMaxPoolSize(int maximumPoolSize);
     
        public long getKeepAliveTime();
     
        public void setKeepAliveTime(long keepAliveTime);
     
        public int getQueueCapacity();
     
        public void setQueueCapacity(int queueCapacity);
     
        public TestRejectedExecutionHandler getTestRejectedExecutionHandler();
     
        public void setTestRejectedExecutionHandler(TestRejectedExecutionHandler testRejectedExecutionHandler);
     
    }

    步骤6:建立TestThreadPoolExecutorService类别

    通过实现ITestThreadPoolExecutorService接口来创建TestThreadPoolExecutorService类。 此类创建一个新的线程池。

    package com.otv.srv;
     
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
     
    import com.otv.handler.TestRejectedExecutionHandler;
     
    /**
     * @author onlinetechvision.com
     * @since 17 Oct 2011
     * @version 1.0.0
     *
     */
    public class TestThreadPoolExecutorService implements ITestThreadPoolExecutorService {
     
        private int  corePoolSize;
        private int  maxPoolSize;
        private long keepAliveTime;
        private int  queueCapacity;
        TestRejectedExecutionHandler testRejectedExecutionHandler;
     
        public ThreadPoolExecutor createNewThreadPool() {
            ThreadPoolExecutor executor = new ThreadPoolExecutor(getCorePoolSize(),
                                                                    getMaxPoolSize(),
                                                                    getKeepAliveTime(),
                                                                    TimeUnit.SECONDS,
                                                                    new ArrayBlockingQueue(getQueueCapacity()),
                                                                    getTestRejectedExecutionHandler());
            return executor;
        }
     
        public int getCorePoolSize() {
            return corePoolSize;
        }
     
        public void setCorePoolSize(int corePoolSize) {
            this.corePoolSize = corePoolSize;
        }
     
        public int getMaxPoolSize() {
            return maxPoolSize;
        }
     
        public void setMaxPoolSize(int maxPoolSize) {
            this.maxPoolSize = maxPoolSize;
        }
     
        public long getKeepAliveTime() {
            return keepAliveTime;
        }
     
        public void setKeepAliveTime(long keepAliveTime) {
            this.keepAliveTime = keepAliveTime;
        }
     
        public int getQueueCapacity() {
            return queueCapacity;
        }
     
        public void setQueueCapacity(int queueCapacity) {
            this.queueCapacity = queueCapacity;
        }
     
        public TestRejectedExecutionHandler getTestRejectedExecutionHandler() {
            return testRejectedExecutionHandler;
        }
     
        public void setTestRejectedExecutionHandler(TestRejectedExecutionHandler testRejectedExecutionHandler) {
            this.testRejectedExecutionHandler = testRejectedExecutionHandler;
        }
    }

    步骤7:创建IThreadPoolMonitorService接口

    IThreadPoolMonitorService接口已创建。

    package com.otv.monitor.srv;
     
    import java.util.concurrent.ThreadPoolExecutor;
     
    public interface IThreadPoolMonitorService extends Runnable {
     
        public void monitorThreadPool();
     
        public ThreadPoolExecutor getExecutor();
     
        public void setExecutor(ThreadPoolExecutor executor);
     
    }

    步骤8:创建ThreadPoolMonitorService类

    ThreadPoolMonitorService类是通过实现IThreadPoolMonitorService接口创建的。 此类监视创建的线程池。

    package com.otv.monitor.srv;
     
    import java.util.concurrent.ThreadPoolExecutor;
    import org.apache.log4j.Logger;
     
    /**
     * @author onlinetechvision.com
     * @since 17 Oct 2011
     * @version 1.0.0
     *
     */
    public class ThreadPoolMonitorService implements IThreadPoolMonitorService {
     
        private static Logger log = Logger.getLogger(ThreadPoolMonitorService.class);
        ThreadPoolExecutor executor;
        private long monitoringPeriod; 
     
        public void run() {
            try {
                while (true){
                    monitorThreadPool();
                    Thread.sleep(monitoringPeriod*1000);
                }
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
     
        public void monitorThreadPool() {
            StringBuffer strBuff = new StringBuffer();
            strBuff.append("CurrentPoolSize : ").append(executor.getPoolSize());
            strBuff.append(" - CorePoolSize : ").append(executor.getCorePoolSize());
            strBuff.append(" - MaximumPoolSize : ").append(executor.getMaximumPoolSize());
            strBuff.append(" - ActiveTaskCount : ").append(executor.getActiveCount());
            strBuff.append(" - CompletedTaskCount : ").append(executor.getCompletedTaskCount());
            strBuff.append(" - TotalTaskCount : ").append(executor.getTaskCount());
            strBuff.append(" - isTerminated : ").append(executor.isTerminated());
     
            log.debug(strBuff.toString());
        }
     
        public ThreadPoolExecutor getExecutor() {
            return executor;
        }
     
        public void setExecutor(ThreadPoolExecutor executor) {
            this.executor = executor;
        }   
     
        public long getMonitoringPeriod() {
            return monitoringPeriod;
        }
     
        public void setMonitoringPeriod(long monitoringPeriod) {
            this.monitoringPeriod = monitoringPeriod;
        }
    }

    第9步:创建入门课程

    启动器类已创建。

    package com.otv.start;
     
    import java.util.concurrent.ThreadPoolExecutor;
     
    import org.apache.log4j.Logger;
     
    import com.otv.handler.TestRejectedExecutionHandler;
    import com.otv.monitor.srv.IThreadPoolMonitorService;
    import com.otv.monitor.srv.ThreadPoolMonitorService;
    import com.otv.srv.ITestThreadPoolExecutorService;
    import com.otv.srv.TestThreadPoolExecutorService;
    import com.otv.task.TestTask;
     
    /**
     * @author onlinetechvision.com
     * @since 17 Oct 2011
     * @version 1.0.0
     *
     */
    public class Starter {
     
        private static Logger log = Logger.getLogger(TestRejectedExecutionHandler.class);
     
        IThreadPoolMonitorService threadPoolMonitorService;
        ITestThreadPoolExecutorService testThreadPoolExecutorService;
     
        public void start() {
     
            // A new thread pool is created...
            ThreadPoolExecutor executor = testThreadPoolExecutorService.createNewThreadPool();
            executor.allowCoreThreadTimeOut(true);
     
            // Created executor is set to ThreadPoolMonitorService...
            threadPoolMonitorService.setExecutor(executor);
     
            // ThreadPoolMonitorService is started...
            Thread monitor = new Thread(threadPoolMonitorService);
            monitor.start();
     
            // New tasks are executed...
            for(int i=1;i<10;i++) {
                executor.execute(new TestTask("Task"+i));
            }
     
            try {
                Thread.sleep(40000);
            } catch (Exception e)   {
                log.error(e.getMessage());
            }
     
            for(int i=10;i<19;i++) {
                executor.execute(new TestTask("Task"+i));
            }
     
            // executor is shutdown...
            executor.shutdown();
        }   
     
        public IThreadPoolMonitorService getThreadPoolMonitorService() {
            return threadPoolMonitorService;
        }
     
        public void setThreadPoolMonitorService(IThreadPoolMonitorService threadPoolMonitorService) {
            this.threadPoolMonitorService = threadPoolMonitorService;
        }
     
        public ITestThreadPoolExecutorService getTestThreadPoolExecutorService() {
            return testThreadPoolExecutorService;
        }
     
        public void setTestThreadPoolExecutorService(ITestThreadPoolExecutorService testThreadPoolExecutorService) {
            this.testThreadPoolExecutorService = testThreadPoolExecutorService;
        }
    }

    步骤10:创建应用程序类

    应用程序类已创建。 此类运行应用程序。

    package com.otv.start;
     
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
     
    /**
     * @author onlinetechvision.com
     * @since 17 Oct 2011
     * @version 1.0.0
     *
     */
    public class Application {
     
        public static void main(String[] args) {
           ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
           Starter starter = (Starter) context.getBean("Starter");
           starter.start();
        }
     
    }

    步骤11:创建applicationContext.xml

    applicationContext.xml已创建。

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
     
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
     
        <!-- Beans Declaration -->
        <bean id="TestTask" class="com.otv.task.TestTask"></bean>
        <bean id="ThreadPoolMonitorService" class="com.otv.monitor.srv.ThreadPoolMonitorService">
            <property name="monitoringPeriod"  value="5" />
        </bean>
        <bean id="TestRejectedExecutionHandler" class="com.otv.handler.TestRejectedExecutionHandler"></bean>
        <bean id="TestThreadPoolExecutorService" class="com.otv.srv.TestThreadPoolExecutorService">
            <property name="corePoolSize"  value="1" />
            <property name="maxPoolSize"   value="3" />
            <property name="keepAliveTime" value="10" />
            <property name="queueCapacity" value="3" />
            <property name="testRejectedExecutionHandler" ref="TestRejectedExecutionHandler" />
        </bean>
        <bean id="Starter" class="com.otv.start.Starter">
            <property name="threadPoolMonitorService" ref="ThreadPoolMonitorService" />
            <property name="testThreadPoolExecutorService" ref="TestThreadPoolExecutorService" />
        </bean>
    </beans>

    步骤12:创建线程池的替代方法

    Spring提供的ThreadPoolTask​​Executor类也可以用于创建线程池。

    <bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
      <property name="corePoolSize"  value="1" />
      <property name="maxPoolSize"   value="3" />
      <property name="queueCapacity" value="3" />
    </bean>
     
    <bean id="testTaskExecutor" class="TestTaskExecutor">
      <constructor-arg ref="threadPoolTaskExecutor" />
    </bean>

    步骤13:建立专案

    生成OTV_Spring_ThreadPool项目后,将创建OTV_Spring_ThreadPool-0.0.1-SNAPSHOT.jar

    步骤14:运行项目

    运行创建的OTV_Spring_ThreadPool-0.0.1-SNAPSHOT.jar文件后,将在下面显示输出日志:

    18.10.2011 20:08:48 DEBUG (TestRejectedExecutionHandler.java:19) - Task7 : has been rejected
    18.10.2011 20:08:48 DEBUG (TestRejectedExecutionHandler.java:19) - Task8 : has been rejected
    18.10.2011 20:08:48 DEBUG (TestRejectedExecutionHandler.java:19) - Task9 : has been rejected
    18.10.2011 20:08:48 DEBUG (TestTask.java:25) - Task1 : is started.
    18.10.2011 20:08:48 DEBUG (TestTask.java:25) - Task6 : is started.
    18.10.2011 20:08:48 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 3 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 2 - CompletedTaskCount : 0 - TotalTaskCount : 5 - isTerminated : false
    18.10.2011 20:08:48 DEBUG (TestTask.java:25) - Task5 : is started.
    18.10.2011 20:08:53 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 3 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 3 - CompletedTaskCount : 0 - TotalTaskCount : 6 - isTerminated : false
    18.10.2011 20:08:58 DEBUG (TestTask.java:27) - Task6 : is completed.
    18.10.2011 20:08:58 DEBUG (TestTask.java:27) - Task1 : is completed.
    18.10.2011 20:08:58 DEBUG (TestTask.java:25) - Task3 : is started.
    18.10.2011 20:08:58 DEBUG (TestTask.java:25) - Task2 : is started.
    18.10.2011 20:08:58 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 3 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 3 - CompletedTaskCount : 2 - TotalTaskCount : 6 - isTerminated : false
    18.10.2011 20:08:58 DEBUG (TestTask.java:27) - Task5 : is completed.
    18.10.2011 20:08:58 DEBUG (TestTask.java:25) - Task4 : is started.
    18.10.2011 20:09:03 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 3 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 3 - CompletedTaskCount : 3 - TotalTaskCount : 6 - isTerminated : false
    18.10.2011 20:09:08 DEBUG (TestTask.java:27) - Task2 : is completed.
    18.10.2011 20:09:08 DEBUG (TestTask.java:27) - Task3 : is completed.
    18.10.2011 20:09:08 DEBUG (TestTask.java:27) - Task4 : is completed.
    18.10.2011 20:09:08 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 3 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 0 - CompletedTaskCount : 6 - TotalTaskCount : 6 - isTerminated : false
    18.10.2011 20:09:13 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 3 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 0 - CompletedTaskCount : 6 - TotalTaskCount : 6 - isTerminated : false
    18.10.2011 20:09:18 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 0 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 0 - CompletedTaskCount : 6 - TotalTaskCount : 6 - isTerminated : false
    18.10.2011 20:09:23 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 0 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 0 - CompletedTaskCount : 6 - TotalTaskCount : 6 - isTerminated : false
    18.10.2011 20:09:28 DEBUG (TestTask.java:25) - Task10 : is started.
    18.10.2011 20:09:28 DEBUG (TestRejectedExecutionHandler.java:19) - Task16 : has been rejected
    18.10.2011 20:09:28 DEBUG (TestRejectedExecutionHandler.java:19) - Task17 : has been rejected
    18.10.2011 20:09:28 DEBUG (TestRejectedExecutionHandler.java:19) - Task18 : has been rejected
    18.10.2011 20:09:28 DEBUG (TestTask.java:25) - Task14 : is started.
    18.10.2011 20:09:28 DEBUG (TestTask.java:25) - Task15 : is started.
    18.10.2011 20:09:28 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 3 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 3 - CompletedTaskCount : 6 - TotalTaskCount : 12 - isTerminated : false
    18.10.2011 20:09:33 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 3 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 3 - CompletedTaskCount : 6 - TotalTaskCount : 12 - isTerminated : false
    18.10.2011 20:09:38 DEBUG (TestTask.java:27) - Task10 : is completed.
    18.10.2011 20:09:38 DEBUG (TestTask.java:25) - Task11 : is started.
    18.10.2011 20:09:38 DEBUG (TestTask.java:27) - Task14 : is completed.
    18.10.2011 20:09:38 DEBUG (TestTask.java:27) - Task15 : is completed.
    18.10.2011 20:09:38 DEBUG (TestTask.java:25) - Task12 : is started.
    18.10.2011 20:09:38 DEBUG (TestTask.java:25) - Task13 : is started.
    18.10.2011 20:09:38 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 3 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 3 - CompletedTaskCount : 9 - TotalTaskCount : 12 - isTerminated : false
    18.10.2011 20:09:43 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 3 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 3 - CompletedTaskCount : 9 - TotalTaskCount : 12 - isTerminated : false
    18.10.2011 20:09:48 DEBUG (TestTask.java:27) - Task11 : is completed.
    18.10.2011 20:09:48 DEBUG (TestTask.java:27) - Task13 : is completed.
    18.10.2011 20:09:48 DEBUG (TestTask.java:27) - Task12 : is completed.
    18.10.2011 20:09:48 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 0 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 0 - CompletedTaskCount : 12 - TotalTaskCount : 12 - isTerminated : true
    18.10.2011 20:09:53 DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize : 0 - CorePoolSize : 1 - MaximumPoolSize : 3 - ActiveTaskCount : 0 - CompletedTaskCount : 12 - TotalTaskCount : 12 - isTerminated : true

    步骤15:下载

    OTV_Spring_ThreadPool

    参考: 如何使用我们JCG合作伙伴提供的 Spring开发和监视线程池服务   在线技术愿景博客的Eren Avsarogullari。


    翻译自: https://www.javacodegeeks.com/2012/02/spring-thread-pool-services.html

    spring 线程池

    展开全文
  • Spring 线程池

    千次阅读 2019-02-18 16:21:43
    -- Spring线程池 --&gt;  &lt;bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"&gt;  &lt;!-- 核心线程数 最小xianc--&...

    springmvc-servlet.xml配置文件

      <!-- Spring线程池  -->
      <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
          <!-- 核心线程数 最小xianc-->
          <property name="corePoolSize" value="3" />
          <!-- 最大线程数 -->
          <property name="maxPoolSize" value="10" />
          <!-- 队列最大长度 >=mainExecutor.maxSize -->
          <property name="queueCapacity" value="25" />
          <!-- 线程池维护线程所允许的空闲时间 -->
          <property name="keepAliveSeconds" value="3000" />
          <!-- 线程池对拒绝任务(无线程可用)的处理策略 ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃. -->
          <property name="rejectedExecutionHandler">
              <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
          </property>
      </bean>

    属性字段说明:

    corePoolSize: 线程池的基本大小,即在没有任务需要执行的时候线程池的大小,并且只有在工作队列满了的情况下才会创建超出这个数量的线程。这里需要注意的是:再刚刚创建ThreadPoolExecutor的时候。线程不会立刻启动,而是要等到有任务提交时才会启动,除非调用方法事先启动核心线程。所以,没有任务需要执行的时候,线程池的大小不一定是corePoolSize;

    maxPoolSize: 线程池中允许的最大线程数,线程池中的当前线程数不会超过该值。如果队列中的任务已满,并且当前线程数小于maxPoolSize,就会创建新的线程来执行任务。

    提交任务:

    1.无返回值的任务使用execute(Runnable)

    2.有返回值得任务使用submit(Runnable)

    新提交一个任务时的处理流程:

    1.如果线程池的当前大小没有达到核心线程池数量(poolSize < corePoolSize),那么就新建一个线程处理新提交的任务;

    2.如果当前大小已经达到核心线程池数量。就将新提交的任务提交到阻塞队列排队。等候处理workQueue.offer(command);

    3.如果队列容量已经达到上限,并且当前大小poolSize没有达到maxPoolSize,那么就新增线程来处理任务;

    4.如果队列已满,并且当前线程数量已经达到上限,那么意味着线程池的处理能力已经达到了极限,此时需要拒绝新增加的任务。至于如何拒绝处理新增的任务,取决于线程池的饱和策略RejectedExecutionHandler。

    rejectedExecutionHandler 字段用于配置拒绝策略,常用的拒绝策略如下:

    一、AbortPolicy

    二、DiscardPolicy

    三、DiscardOldestPolicy

    四、CallerRunsPolicy

    五、自定义

    第一种:AbortPolicy

    该策略是线程池的默认策略。使用该策略时,如果线程池和队列都满了,新的任务会被丢弃并且抛出RejectedExecutionException异常;

    源码:

     public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
                //不做任何处理,直接抛出异常
                throw new RejectedExecutionException("Task " + r.toString() +
                                                     " rejected from " +
                                                     e.toString());
            }
     

    第二种:DiscardPolicy

    这个策略,如果线程池和队列都满了,新的任务会被丢弃并且不会产生异常;

    源码:

       public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
                //就是一个空的方法
            }
     

    第三种:DiscardOldestPolicy

    这个策略从字面上理解,对其最老的。即如果线程池和队列都满了,会将最早进入队列的任务删掉腾出空间,再加入队列。由于队列是队尾进,队头出,所以队头元素是最老的,因此每次都是移除队头元素后再尝试入队。

    源码:

            public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
                if (!e.isShutdown()) {
                    //移除队头元素
                    e.getQueue().poll();
                    //再尝试入队
                    e.execute(r);
                }
            }
    第四种:CallerRunsPolicy

    使用此策略,如果添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行。就像是个急脾气的人,等不来别人干,干脆自己干。

    源码:

    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
                if (!e.isShutdown()) {
                    //直接执行run方法
                    r.run();
                }
            }
    第五种:自定义

    如果以上策略都不符合业务场景,那么可以自己定义一个拒绝策略,只要实现RejectedExecutionHandler接口。

    例如:

    public class MyRejectPolicy implements RejectedExecutionHandler{
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            //Sender是我的Runnable类,里面有message字段
            if (r instanceof Sender) {
                Sender sender = (Sender) r;
                //直接打印
                System.out.println(sender.getMessage());
            }
        }
    }

    以上5种策略没有好坏之分,只是使用不同的场景,具体哪种适合得根据具体场景和业务来做选择

    以下博客提供帮助:

    https://blog.csdn.net/jgteng/article/details/54411423

    https://blog.csdn.net/foreverling/article/details/78073105

     

     

     

     

    展开全文
  • spring线程池

    2017-02-22 15:13:49
    配置spring线程池-->           2.编写线程方法 import org.springframework.stereotype.Component; @Component public class ThreadTest implements Runnable{ privat


    1.配置spring.xml文件

    <!--  配置spring线程池-->
    <bean id ="taskExecutor"  class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >
        <property name ="corePoolSize" value ="5" />
        <property name ="keepAliveSeconds" value ="300" />
        <property name ="maxPoolSize" value ="10" />
        <property name ="queueCapacity" value ="25" />
      </bean>


    2.编写线程方法

    import org.springframework.stereotype.Component;


    @Component
    public class ThreadTest implements Runnable{


    private String name;

    public ThreadTest(String name) {
    // TODO Auto-generated constructor stub
    this.name = name;
    }
    @Override
    public void run() {
    // TODO Auto-generated method stub
    System.out.println(getName() + " is running.");  
             try{  
                     Thread.sleep(5000);  
             }catch(InterruptedException e){  
                     e.printStackTrace();  
             }  
             System.out.println(getName() + " is running again.");  
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }

    }

    3.运用线程池(我在servlet里面运用线程池)

    @Service
    public class BorrowService {

    @Autowired
    ThreadPoolTaskExecutor taskExecutor;

    public void threadTest() {


    taskExecutor.execute(new ThreadTest("Thread 1"));
    taskExecutor.execute(new ThreadTest("Thread 2"));
    taskExecutor.execute(new ThreadTest("Thread 3"));
    taskExecutor.execute(new ThreadTest("Thread 4"));
    taskExecutor.execute(new ThreadTest("Thread 5"));
    taskExecutor.execute(new ThreadTest("Thread 6"));
    taskExecutor.execute(new ThreadTest("Thread 7"));
    taskExecutor.execute(new ThreadTest("Thread 8"));
    taskExecutor.execute(new ThreadTest("Thread 9"));
    taskExecutor.execute(new ThreadTest("Thread 10"));

    }

    }


    属性字段说明: 
    corePoolSize: 线程池维护线程的最少数量 
    keepAliveSeconds 线程池维护线程所允许的空闲时间 
    maxPoolSize 线程池维护线程的最大数量 
    queueCapacity 线程池所使用的缓冲队列

    二、execute(Runnable)方法 执行过程

    1. 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。

    2. 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。

    3. 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。

    4. 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程 maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。

    5. 当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。


    展开全文
  • spring 线程池

    2015-12-11 19:58:27
    -- spring线程池 --&gt; &lt;bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"&gt; &lt;!-- 线程池维护线程的最少数量 --...
  • Spring线程池ThreadPoolTaskExecutor配置及详情1. ThreadPoolTaskExecutor配置1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...
  • jdk线程池就是使用jdk线程工具类ThreadPoolExecutor 创建线程池spring线程池就是使用自己配置的线程池,然后交给spring处理,可以采用Async,也可以引入线程池的bean依赖。记一下线程池优化不当导致的资源耗尽原本...
  • Spring线程池demo

    2016-05-25 15:01:34
    Spring 线程池 demo

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,221
精华内容 1,688
热门标签
关键字:

spring线程池

spring 订阅