线程池(重点)

83 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

线程池: 三大方法, 7大参数, 4种拒绝策略

池化技术

程序的运行,本质: 占用系统的资源! 优化资源的使用!=》 池化技术

线程池,连接池,内存池,对象池///.......

池化技术:事先准备好一些资源,有人要用,就来我这里拿:用完之后还给我

线程池的好处

  1. 降低资源的消耗

  2. 提高响应的速度

  3. 方便管理

线程复用,可以控制最大并发数,管理线程

线程

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    
    
 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

都是用ThreadPoolExecutor类

public ThreadPoolExecutor(int corePoolSize,// 核心线程池大小
                          int maximumPoolSize,//最大核心线程池大小
                          long keepAliveTime,// 超时了没有人调用就会释放
                          TimeUnit unit, //超时单位
                          BlockingQueue<Runnable> workQueue, //阻塞对列
                          ThreadFactory threadFactory,  //线程工厂,创建线程的,一般不用动
                          RejectedExecutionHandler handler) {//拒绝策略
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.acc = System.getSecurityManager() == null ?
            null :
            AccessController.getContext();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}
//new ThreadPoolExecutor 拒绝策略
public class TestExcutorPool {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2,
                5,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
//超出最大承载所处理的异常
//new ThreadPoolExecutor.AbortPolicy()); //抛出异常
//new ThreadPoolExecutor.CallerRunsPolicy());//main 处理这个异常
// new ThreadPoolExecutor.DiscardPolicy());//队列满了,不会抛出异常,但会丢掉队列
                new ThreadPoolExecutor.DiscardOldestPolicy());//队列满了 开始竞争,尝试和最早的去竞争,竞争失败,消失,成功进入,也不会抛出异常
        try {
//最大承载=Queue+ max
//超出最大承载
            for (int i = 1; i <= 9; i++) {
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+" OK");
                });
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
//        线程池用完,程序结束,关闭线程池
            threadPool.shutdown();
        }
    }
}

四大函数式接口(必需掌握)

lambda表达式, 链式编程, 函数式接口,Stream流式计算

函数式接口: 只有一个方法的接口

public interface Runnable {//源码
    public abstract void run();
}
//foreach(消费者类的函数式接口)
public class FunctionTest {
    /**
     * Function 函数式接口,有一个输入参数,有一个输出
     * 只要是 函数式接口 可以用lambda表达式简化
     */
    public static void main(String[] args) {

//        Function function = new Function<String,String>(){
//            @Override
//            public String apply(String str) {
//                return str;
//            }
//        };

        Function function = (str)->{return str;};
        System.out.println(function.apply("adn"));
    }
}

断定型接口: 返回值必须为布尔值

public interface Predicate<T> {//源码

    boolean test(T t);
}
public class PredicateTest {
    /**
     * 断定型接口: 有一个输入值参数返回值必须为boolean值
     * @param
     */
    public static void main(String[] args) {
//        Predicate<String> predicate = new Predicate<String>(){
//            @Override
//            public boolean test(String str) {
//                return str.isEmpty();
//            }
//        };
        Predicate<String> predicate = (str)->{return str.isEmpty();};
        System.out.println(predicate.test(""));
    }
}

Consumer 消费型接口只有输入,没有返回值

public interface Consumer<T> {//源码

    void accept(T t);
 }
public class ConsumerTest {
    public static void main(String[] args) {
//        Consumer<String> consumer = new Consumer<String>(){
//            @Override
//            public void accept(String str) {
//                System.out.println(str);
//            }
//        };
        Consumer<String> consumer = (str)->{
            System.out.println(str);
        };
        consumer.accept("ert");

    }
}

Supplier 供给型接口

public interface Supplier<T> {//源码
    T get();
}
public class SupplierTest {
    public static void main(String[] args) {
//        Supplier<Integer> supplier = new Supplier<Integer>() {
//            @Override
//            public Integer get() {
//                System.out.println("进入get()方法");
//                return 1024;
//            }
//        };
        Supplier supplier = ()->{return 1024;};
        System.out.println(supplier.get());
    }
}

CPU密集型与 IO密集型

CPU密集型(CPU-bound)与 IO密集型(I/O bound) 我们可以把任务分为计算密集型和IO密集型。

计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如计算圆周率、对视频进行高清解码等等,全靠CPU的运算能力。

第二种任务的类型是IO密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。