线程基础:线程池(5)——基本使用(上)

发布时间:2017-7-1 11:26:02编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"线程基础:线程池(5)——基本使用(上) ",主要涉及到线程基础:线程池(5)——基本使用(上) 方面的内容,对于线程基础:线程池(5)——基本使用(上) 感兴趣的同学可以参考一下。

来源:http://blog.csdn.net/yinwenjie

1、概述

从本文开始,我将用两篇文章的篇幅,为各位读者呈现Java中原生的线程池技术。第一篇文章,我将讲解JAVA原生线程池的基本使用,并由此延伸出JAVA中和线程管理相关的类结构体系,然后我们详细描述JAVA原生线程池的结构和工作方式;第二篇文章,我们将继续深入,讲解JAVA原生线程池的高级特性,包括Thread工厂、队列、拒绝原则、钩子和相关工具类。

如果您是JAVA语言的初学者,请从本篇文章看起;如果您对线程池技术已有一定的了解,那么可以只看下一篇文章;如果您是高手,请绕行;如果您对我的观点有任何意见和建议,请留言,谢谢。^-^

2、为什么要使用线程池

这里写图片描述

前文我们已经讲到,线程是一个操作系统概念。操作系统负责这个线程的创建、挂起、运行、阻塞和终结操作。而操作系统创建线程、切换线程状态、终结线程都要进行CPU调度——这是一个耗费时间和系统资源的事情(《操作系统知识回顾—进程线程模型》

另一方面,目前大多数生产环境我们所面临问题的技术背景一般是:处理某一次请求的时间是非常短暂的,但是请求数量是巨大的。这种技术背景下,如果我们为每一个请求都单独创建一个线程,那么物理机的所有资源基本上都被操作系统创建线程、切换线程状态、销毁线程这些操作所占用,用于业务请求处理的资源反而减少了。所以最理想的处理方式是,将处理请求的线程数量控制在一个范围,既保证后续的请求不会等待太长时间,又保证物理机将足够的资源用于请求处理本身

另外,一些操作系统是有最大线程数量限制的。当运行的线程数量逼近这个值的时候,操作系统会变得不稳定。这也是我们要限制线程数量的原因。

3、线程池的基本使用方式

JAVA语言为我们提供了两种基础线程池的选择:ScheduledThreadPoolExecutor和ThreadPoolExecutor。它们都实现了ExecutorService接口(注意,ExecutorService接口本身和“线程池”并没有直接关系,它的定义更接近“执行器”,而“使用线程管理的方式进行实现”只是其中的一种实现方式)。这篇文章中,我们主要围绕ThreadPoolExecutor类进行讲解。

3-1、简单使用

首先我们来看看ThreadPoolExecutor类的最简单使用方式:

package test.thread.pool;

import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.BasicConfigurator;

public class PoolThreadSimple {

    static {
        BasicConfigurator.configure();
    }

    public static void main(String[] args) throws Throwable {

        /*
         * corePoolSize:核心大小,线程池初始化的时候,就会有这么大
         * maximumPoolSize:线程池最大线程数
         * keepAliveTime:如果当前线程池中线程数大于corePoolSize。
         * 多余的线程,在等待keepAliveTime时间后如果还没有新的线程任务指派给它,它就会被回收
         * 
         * unit:等待时间keepAliveTime的单位
         * 
         * workQueue:等待队列。这个对象的设置是本文将重点介绍的内容
         * */
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 10, 1, TimeUnit.MINUTES, new SynchronousQueue<Runnable>());
        for(int index = 0 ; index < 10 ; index ++) {
            poolExecutor.submit(new PoolThreadSimple.TestRunnable(index));
        }

        // 没有特殊含义,只是为了保证main线程不会退出
        synchronized (poolExecutor) {
            poolExecutor.wait();
        }
    }

    /**
     * 这个就是测试用的线程
     * @author yinwenjie
     */
    private static class TestRunnable implements Runnable {

        /**
         * 日志
         */
        private static Log LOGGER = LogFactory.getLog(TestRunnable.class);

        /**
         * 记录任务的唯一编号,这样在日志中好做识别
         */
        private Integer index;

        public TestRunnable(int index) {
            this.index = index;
        }

        /**
         * @return the index
         */
        public Integer getIndex() {
            return index;
        }

        @Override
        public void run() {
            /*
             * 线程中,就只做一件事情:
             * 等待60秒钟的事件,以便模拟业务操作过程
             * */
            Thread currentThread  = Thread.currentThread();
            TestRunnable.LOGGER.info("线程:" + currentThread.getId() + " 中的任务(" + this.getIndex() + ")开始执行===");
            synchronized (currentThread) {
                try {
                    currentThread.wait(60000);
                } catch (InterruptedException e) {
                    TestRunnable.LOGGER.error(e.getMessage(), e);
                }
            }

            TestRunnable.LOGGER.info("线程:" + currentThread.getId() + " 中的任务(" + this.getIndex() + ")执行完成");
        }


上一篇:http://blog.csdn.net/u011277123/article/details/53665302
下一篇:js学习——基础知识

相关文章

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。

好贷网好贷款