java 线程池

java线程池

什么是线程池?
线程池就是一个容器,把创建的若干个线程放入这个容器中,当处理任务需要运行线程时,线程池会将线程提交到任务队列中,处理完之后线程并不会被销毁,而是仍然处于线程中,等待下一任务,如果之后还有任务要使用这个线程,该线程会再次被提交到任务队列中。

使用线程池的优点

  1. java中创建线程,需要为线程分配一系列资源,假如创建线程的时间为t1,线程执行的任务时间为t2,线程销毁的时间为t3,而往往t1+t3>t2,频繁地创建和销毁线程效率将会非常低
    2.线程池中的线程不会被销毁,有任务需要时,直接可以提交到任务队列
  2. 线程池可以统一分配线程,方便调优和监控,可以提高系统稳定性

线程池有哪些类型

1.newCachedThreadPool

一种可以缓存的线程池,若是线程池长度超过了处理需要,将会灵活回收空闲线程,若是没有课回收的线程,则会创建新的线程。该线程池容量为无限大,当执行第二个任务时,如果需要第一个已完成任务中执行过的线程,那么线程池可以重复调用,不需要重新创建新的线程。

实例代码如下:

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    for (int i = 0; i < 10; i++) {
        final int index = i;
    try {
        Thread.sleep(index * 1000);
    } 
        catch (InterruptedException e) {
            e.printStackTrace();
    }

cachedThreadPool.execute(new Runnable() {

@Override
public void run() {
    System.out.println(index);
}
});
}

2 newFixedThreadPool

一种固定大小的线程池,可以控制线程最大并发数,超出的线程会在队列中等待,定长线程池的大小可以根据系统资源进行设置。
示例代码:

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
    for (int i = 0; i < 10; i++) {
    final int index = i;

    fixedThreadPool.execute(new Runnable() {

@Override
public void run() {
try {
    System.out.println(index);
    Thread.sleep(2000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
}
});
}

因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字

3 newScheduledThreadPool

一种定长的线程池,支持定时或者周期性地执行线程。

延迟3秒执行的示例代码:

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
 scheduledThreadPool.schedule(new Runnable() {

@Override
public void run() {
    System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);

表示定长为5,延迟3秒执行的线程池

延迟1秒后每3秒执行一次,周期性执行的示例代码:

scheduledThreadPool.scheduleAtFixedRate(new Runnable() {

@Override
public void run() {
    System.out.println("delay 1 seconds, and excute every 3 seconds");
}
}, 1, 3, TimeUnit.SECONDS);

4 newSingleThreadExecutor

一种单线程化的线程池,它会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。示例代码如下:

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {

@Override
public void run() {
    try {
        System.out.println(index);
    Thread.sleep(2000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
        }
}
    });
}

结果按照顺序输出

线程池中的参数

  1. corePoolSize:核心池大小
  2. maximumPoolSize:线程池最大线程数。
  3. keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有线程数大于核心线程corePoolSize时,该参数才会起作用
  4. unit:参数keepAliveTime的时间单位
  5. workQueue:一个阻塞队列,用来存储等待执行的任务,有以下几种选择,ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue.
    6.threadFactory:线程工厂,主要用来创建线程
  6. handler:便是当拒绝处理任务时的策略,四种取值:
    ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
    ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
    ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
    ThreadPoolExecutor.CallerRunsPolicy:由点用线程处理该任务。

线程池状态总结图:

参考博文:https://www.jianshu.com/p/174958a72ce9
https://www.cnblogs.com/ConstXiong/p/11686245.html

posted @ 2020-09-06 18:41  TidalCoast  阅读(93)  评论(0编辑  收藏  举报