Java多线程优化之线程池的使用方法

Java多线程优化之线程池

java标准库提供了ExecutorService接口表示线程池
创建这些线程池的方法都被封装到Executors这个类


一、FixedThreadPool

FixedThreadPool:线程数固定的线程池

public class ThreadPoolTest01 {
    public static void main(String[] args) {
    	//创建一个线程数固定为6的线程池
        ExecutorService es = Executors.newFixedThreadPool(6);
        for (int i = 0; i < 6; i++) {
            es.submit(new Task01("start task" + i));
        }
        // 关闭线程池:
        es.shutdown();
    }

}
class Task01 implements Runnable{
    private final String name;

    public Task01(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("start task " + name);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        System.out.println("end task " + name);
    }
}

运行后:

start task start task0
start task start task3
start task start task1
start task start task2
start task start task4
start task start task5
end task start task3
end task start task2
end task start task5
end task start task1
end task start task4
end task start task0

二、CachedThreadPool

CachedThreadPool:线程数根据任务动态调整的线程池

public class ThreadPoolTest02 {
    public static void main(String[] args) {
        ExecutorService es = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            es.submit(new Task02("start task" + i));
        }
        es.shutdown();
    }
}

class Task02 implements Runnable{
    private final String name;

    public Task02(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("start task " + name);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        System.out.println("end task " + name);
    }
}

运行后:

start task start task0
start task start task1
start task start task2
start task start task3
start task start task4
end task start task1
end task start task0
end task start task3
end task start task4
end task start task2

如果想控制线程池的大小呢?首先看一下Executors.newCachedThreadPool()方法的源码:
MAX_VALUE = 0x7fffffff

/**
     * Creates a thread pool that creates new threads as needed, but
     * will reuse previously constructed threads when they are
     * available.  These pools will typically improve the performance
     * of programs that execute many short-lived asynchronous tasks.
     * Calls to {@code execute} will reuse previously constructed
     * threads if available. If no existing thread is available, a new
     * thread will be created and added to the pool. Threads that have
     * not been used for sixty seconds are terminated and removed from
     * the cache. Thus, a pool that remains idle for long enough will
     * not consume any resources. Note that pools with similar
     * properties but different details (for example, timeout parameters)
     * may be created using {@link ThreadPoolExecutor} constructors.
     *
     * @return the newly created thread pool
     */
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

可以这样实现:

int min = 5;
int max = 10;
ExecutorService es = new ThreadPoolExecutor(min, max,
        60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());

第一个参数min 表示这个线程池初始化了5个线程在里面工作
第二个参数max 表示如果5个线程不够用了,就会自动增加到最多10个线程
第三个参数60 结合第四个参数TimeUnit.SECONDS,表示经过60秒,多出来的线程还没有接到活儿,就会回收,最后保持池子里就5个
第四个参数TimeUnit.SECONDS 如上
第五个参数 new LinkedBlockingQueue() 用来放任务的集合

三、SingleThreadExecutor

SingleThreadExecutor:仅单线程执行的线程池
适用场景:任务需要定期反复执行

public class ThreadPoolTest03 {
    public static ScheduledExecutorService ses = Executors.newScheduledThreadPool(4);

    public static void main(String[] args) {
        //一秒后执行一次性任务
        ses.schedule(new Task03("one-time"), 1, TimeUnit.SECONDS);
        //2秒后开始执行定时任务,每3秒执行  
        //FixedRate是指任务总是以固定时间间隔触发,不管任务执行多长时间
        ses.scheduleAtFixedRate(new Task03("fixed-rate"), 2, 3, TimeUnit.SECONDS);
        //2秒后开始执行定时任务,以3秒为间隔执行 
        //FixedDelay是指,上一次任务执行完毕后,等待固定的时间间隔,再执行下一次任务
        ses.scheduleWithFixedDelay(new Task03("fixed-delay"),2,3,TimeUnit.SECONDS);
    }

}
class Task03 implements Runnable{
    private final String name;

    public Task03(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("start task " + name);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        System.out.println("end task " + name);
    }
}

注意

线程池在程序执行完必须要关闭
1.调用shutdown()时,线程池的状态则立刻变成SHUTDOWN状态。此时,则不能再往线程池中添加任何任务,否则将会抛出RejectedExecutionException异常。
2.调用awaitTermination()则会等待指定的时间让线程池关闭。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只努力的笨笨熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值