自定义线程池

如果当前线程池中的线程数目小于corePoolSize,则每来一个任务,就会创建一个线程去执行这个任务;

如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到任务缓存队列当中,若添加成功,则该任务会等待空闲线程将其取出去执行;若添加失败(一般来说是任务缓存队列已满),则会尝试创建新的线程去执行这个任务;

如果队列已经满了,则在总线程数不大于maximumPoolSize的前提下,则创建新的线程

如果当前线程池中的线程数目达到maximumPoolSize,则会采取任务拒绝策略进行处理;

如果线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止,直至线程池中的线程数目不大于corePoolSize;如果允许为核心池中的线程设置存活时间,那么核心池中的线程空闲时间超过keepAliveTime,线程也会被终止。

废话不多说,上手撸代码!

先把这个代码copy到你的main函数,毕竟都是这个封装的,咱们也封装封装玩玩~

               new ThreadPoolExecutor(nThreads, nThreads,
                                              0L, TimeUnit.MILLISECONDS,
                                              new LinkedBlockingQueue<Runnable>());
             

然后封装到这个样子:

package com.toov5.ThreadPoolTest;

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

class TaskThread implements Runnable{
     private String threadName;
    public TaskThread(String thradName) {
        this.threadName=thradName;
    }     
     @Override
    public void run() {
        System.out.println(threadName);
    }
     
     
}  

public class DefinedThreadPool {

       public static void main(String[] args) {
           //核心线程数1 最大线程数2    1是实际运行的线程数 2是最多可以创建的线程数    后面的表示存活的时间(如果线程有空闲 超时时间 节约内存回收掉)
           //这里是0L 用完就杀死了 不回收了 最好设置超时时间 配置30s 有时候配置太长线程不能立马被复用到 太短容易产生超时
           //单位是毫秒 
           //队列的初始化值是3 
        ThreadPoolExecutor threadPoolExecutor =  new ThreadPoolExecutor(1, 2,
                                              0L, TimeUnit.MILLISECONDS,
                                              new LinkedBlockingQueue<Runnable>(3));

        
        //任务1现在创建线程 执行
        threadPoolExecutor.execute(new TaskThread("任务1"));
        //两个任务 任务2大于1 此时的队列大小是(3)没有满 那么任务2进入队列
        threadPoolExecutor.execute(new TaskThread("任务2"));
        threadPoolExecutor.execute(new TaskThread("任务3"));
       } 
  
    }       
       
       
    

任务 2 任务3 此时放到队列去了

 结果:

下面搞坏他!哈哈哈

package com.toov5.ThreadPoolTest;

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

class TaskThread implements Runnable{
     private String threadName;
    public TaskThread(String thradName) {
        this.threadName=thradName;
    }     
     @Override
    public void run() {
        System.out.println(threadName);
    }
     
     
}  

public class DefinedThreadPool {

       public static void main(String[] args) {
           //核心线程数1 最大线程数2    1是实际运行的线程数 2是最多可以创建的线程数    后面的表示存活的时间(如果线程有空闲 超时时间 节约内存回收掉)
           //这里是0L 用完就杀死了 不回收了 最好设置超时时间 配置30s 有时候配置太长线程不能立马被复用到 太短容易产生超时
           //单位是毫秒 
           //队列的初始化值是3 
        ThreadPoolExecutor threadPoolExecutor =  new ThreadPoolExecutor(1, 2,
                                              0L, TimeUnit.MILLISECONDS,
                                              new LinkedBlockingQueue<Runnable>(3));

        
        //任务1现在创建线程 执行
        threadPoolExecutor.execute(new TaskThread("任务1"));
        //两个任务 任务2大于1 此时的队列大小是(3)没有满 那么任务2进入队列
        threadPoolExecutor.execute(new TaskThread("任务2"));
        threadPoolExecutor.execute(new TaskThread("任务3"));
        threadPoolExecutor.execute(new TaskThread("任务4"));
        threadPoolExecutor.execute(new TaskThread("任务5"));
        threadPoolExecutor.execute(new TaskThread("任务6"));
       } 
  
    }       
       
       
    

看吧:

报错了!

 分析下:

package com.toov5.ThreadPoolTest;

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

class TaskThread implements Runnable{
     private String threadName;
    public TaskThread(String thradName) {
        this.threadName=thradName;
    }     
     @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+threadName);
    }
     
     
}  

public class DefinedThreadPool {

       public static void main(String[] args) {
           //核心线程数1 最大线程数2    1是实际运行的线程数 2是最多可以创建的线程数    后面的表示存活的时间(如果线程有空闲 超时时间 节约内存回收掉)
           //这里是0L 用完就杀死了 不回收了 最好设置超时时间 配置30s 有时候配置太长线程不能立马被复用到 太短容易产生超时
           //单位是毫秒 
           //队列的初始化值是3 
        ThreadPoolExecutor threadPoolExecutor =  new ThreadPoolExecutor(1, 2,
                                              0L, TimeUnit.MILLISECONDS,
                                              new LinkedBlockingQueue<Runnable>(3));

        
        //任务1现在创建线程 执行
        threadPoolExecutor.execute(new TaskThread("任务1"));
        //两个任务 任务2大于1 此时的队列大小是(3)没有满 那么任务2进入队列
        threadPoolExecutor.execute(new TaskThread("任务2"));
        threadPoolExecutor.execute(new TaskThread("任务3"));
        threadPoolExecutor.execute(new TaskThread("任务4"));
        threadPoolExecutor.execute(new TaskThread("任务5"));
//        threadPoolExecutor.execute(new TaskThread("任务6"));
       } 
  
    }       
       
       

 

线程就两个 1和2 来回复用  线程池就一个

最大线程数+队列缓存数      一旦超过就报错

大家可以自己玩玩体验一把,如果我执行的是1-5的任务 那么都是线程1 2 来复用

但是如果超过了 队列数+核心线程数 那么就要创新信的线程了,大家可以试试玩玩

核心线程数 是实际运行的线程数  

最大线程数 是可以创建的线程数   大于等于最大线程数那么会 拒绝任务了

如果超出了队列数量并且没有超出最大线程数 则创建新的线程 并且也会加入复用的行列

保证所有真正线程都能 被实际用到 核心线程数 实际运行的线程

最大线程数 最多可以创建多少个线程

大家可以这么理解 

原文地址:https://www.cnblogs.com/toov5/p/9836008.html