Java 并发编程 之 线程池(四)

线程池

  • 常见使用场景
    • Web/数据库/文件/邮件 服务器
    • 请求来自远程的客户端
    • 请求数量很大, 任务执行时间较短
  • 一个请求一个线程

    • 创建线程,销毁线程的开销比较大
    • 太多的线程导致内存耗尽
  • 复用一个资源的技术,前提是请求数量很大, 任务执行时间较短

  • 线程池

    • 系统预先创建指定数量的线程
    • 对多任务重用线程, 线程创建的开销被分摊
    • 请求到来时, 线程已经存在, 立刻就可以服务
    • 通过限制线程池中的线程数量, 防止资源不足
      这里写图片描述

关于线程池的思考

  • 当线程池刚刚创立,还没有Task到来的时候, 池中的线程处于什么状态?
    • 阻塞状态(block)
  • 当Task到来的时候,线程池中的线程如何得到通知?
    • notify(),任务来了就唤醒某一个线程
  • 当线程池中的线程完成工作,如何回到池中?
    • 回去阻塞队列中取任务,如果发现没有任务就会放入线程池
  • Task是个什么东西?
    • 自定义的结构能被线程识别

线程池的本质就是一个阻塞队列

线程池例子: WorkerThread

通过下面这个例子了解线程池的原理

public interface Task {
    public void execute();
}

public class ThreadPool {
    private BlockingQueue taskQueue = null;
    private List<WorkerThread> threads = new ArrayList<WorkerThread>();
    private boolean isStopped = false;


    public ThreadPool( int numOfThreads, int maxNumOfTasks ){
        //阻塞队列
        taskQueue = new BlockingQueue( maxNumOfTasks );

        for( int i=0; i<numOfThreads; i++ ){
            //将阻塞队列放入线程池中
            threads.add( new WorkerThread( taskQueue ) );
        }
        //把所有线程都启动
        for (WorkerThread thread : threads) {
            thread.start();
        }
    }

    public synchronized void execute( Task task ) throws Exception{
        if(this.isStopped)
            throws IllegalStateException("ThreadPool is stopped");
        //添加任务
        this.taskQueue.enqueue(task);
    }

    public synchronized void stop(){
        this.isStopped = true;
        for(WorkerThread thread : threads){
            thread.doStop();
        }
    }

}

public class WorkerThread extends Thread {
    private BlockingQueue taskQueue = null;
    private boolean       isStopped = false;

    public WorkerThread( BlockingQueue queue ) {
        taskQueue = queue;
    }

    public void run(){
        while( !isStopped ){
            try{
                //核心:下面的调用如果没有取到任务会阻塞
                Task task = (Task)taskQueue.dequeue();
                task.execute();
            } catch (Exception e){

            }
        }
    }

    public synchronized void doStop(){
        isStopped = true;
        //为什么调用中断的方法:因为某些任务可能处于阻塞的状态。
        //跳出wait调用。
        this.interrupt();
    }

    public synchronized boolean isStopped(){
        return isStopped;
    }
}

从JDK1.5以后, 不用自己写线程池了

传送门

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值