首页 > 代码库 > 多线程简单实例(3)线程池

多线程简单实例(3)线程池

为什么要用线程池?

每次用线程的时候都去new一个,不麻烦么。如果线程用到较少可以。当需要大量用到线程时,频繁的创建线程,而且创建线程和销毁带来的开销也会随之增多。

线程池就像一个执行器。而我们需要执行的业务逻辑,在我们编写的实现了Runnable接口的run方法里面。

需要执行就扔到线程池里,我只要保证我的业务逻辑在run里面已经实现了。执行找线程池这个代工。

线程池ThreadPoolExecutor类,下面是该类的构造方法。

public class ThreadPoolExecutor extends AbstractExecutorService {
    .....
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue);
 
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);
 
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);
 
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
        BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
    ...
}

主要参数介绍:

corePoolSize:核心线程数
maximumPoolSize:最大线程数(可以想象成cpu中的超超频)
keepAliveTime:线程无任务存活时间(一般情况下,当前线程数poolSize大于corePoolSize时,会销毁空闲时间大于keepAliveTime的线程,直到当前线程数不大于corePoolSize)
unit:keepAliveTime的单位(
TimeUnit.DAYS;               //天
TimeUnit.HOURS;             //小时
TimeUnit.MINUTES;           //分钟
TimeUnit.SECONDS;           //秒
TimeUnit.MILLISECONDS;      //毫秒
TimeUnit.MICROSECONDS;      //微妙
TimeUnit.NANOSECONDS;       //纳秒


BlockingQueue<Runnable>:缓存队列中允许最大的任务线程数(当线程数大于maxnumPoolSize时,将加入到缓存队列中)
ThreaPoolExecutor的一些方法:
execute():线程池加入线程
submit():线程池加入线程(和execute方法一样,只不过会返回一个参数。ps:其实submit内部也是调用了execute方法)
shutdown():关闭线程池(若线程池和缓存中还有未执行完的线程,则会继续执行,执行完清空线程池。)
shutdownNow():马上关闭线程池(若线程池中还有未执行完的线程,则会抛出异常)

简单的例子:
package code.thread;

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

//线程池
public class ThreadPool {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MICROSECONDS, 
                new ArrayBlockingQueue<Runnable>(5));
        for(int i=0;i<15;i++){
            threadPool.execute(new Task(i));
            System.out.println("线程池中的线程数:"+threadPool.getPoolSize()+"  队列中等待的线程数:"+
            threadPool.getQueue().size()+"  已执行完的线程数:"+threadPool.getCompletedTaskCount());
        }
        {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        System.out.println("线程池中的线程数:"+threadPool.getPoolSize()+"  队列中等待的线程数:"+
                threadPool.getQueue().size()+"  已执行完的线程数:"+threadPool.getCompletedTaskCount());
        
        }
        threadPool.shutdown();
        
        
    }
}

class Task implements Runnable {
    private int i;
    public Task(int i) {
        this.i = i;
    }
    @Override
    public void run() {
        System.out.println("task:"+i+"执行");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("task:"+i+"执行结束");
        
    }
    
}

执行结果:

task:0执行
线程池中的线程数:1 队列中等待的线程数:0 已执行完的线程数:0
线程池中的线程数:2 队列中等待的线程数:0 已执行完的线程数:0
task:1执行
线程池中的线程数:3 队列中等待的线程数:0 已执行完的线程数:0
task:2执行
线程池中的线程数:4 队列中等待的线程数:0 已执行完的线程数:0
task:3执行
线程池中的线程数:5 队列中等待的线程数:0 已执行完的线程数:0
task:4执行
线程池中的线程数:5 队列中等待的线程数:1 已执行完的线程数:0
线程池中的线程数:5 队列中等待的线程数:2 已执行完的线程数:0
线程池中的线程数:5 队列中等待的线程数:3 已执行完的线程数:0
线程池中的线程数:5 队列中等待的线程数:4 已执行完的线程数:0
线程池中的线程数:5 队列中等待的线程数:5 已执行完的线程数:0
线程池中的线程数:6 队列中等待的线程数:5 已执行完的线程数:0
task:10执行
线程池中的线程数:7 队列中等待的线程数:5 已执行完的线程数:0
task:11执行
task:12执行
线程池中的线程数:8 队列中等待的线程数:5 已执行完的线程数:0
线程池中的线程数:9 队列中等待的线程数:5 已执行完的线程数:0
task:13执行
task:14执行
线程池中的线程数:10 队列中等待的线程数:5 已执行完的线程数:0
task:0执行结束
task:2执行结束
task:5执行
task:1执行结束
task:6执行
task:3执行结束
task:8执行
task:4执行结束
task:9执行
task:13执行结束
task:7执行
task:10执行结束
task:11执行结束
task:12执行结束
task:14执行结束
task:5执行结束
task:6执行结束
task:7执行结束
task:9执行结束
task:8执行结束
线程池中的线程数:5 队列中等待的线程数:0 已执行完的线程数:15

 

多线程简单实例(3)线程池