线程池

158 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第三十四天,点击查看活动详情

1、SynchronousQueue

在这里插入图片描述

package com.blockingqueue;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

/**
 * 同步队列  SynchronousQueue不存储元素,put了一个元素,必须从里边先取出来,然后再放入
 */
public class SynchronousQueueDemo {
    public static void main(String[] args) {
        BlockingQueue<String> blockingQueue = new SynchronousQueue<>();//同步队列

        new Thread(()->{

            try {
                System.out.println(Thread.currentThread().getName()+"put1");
                blockingQueue.put("1");
                System.out.println(Thread.currentThread().getName()+"put2");
                blockingQueue.put("2");
                System.out.println(Thread.currentThread().getName()+"put3");
                blockingQueue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();


        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+blockingQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+blockingQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+blockingQueue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"B").start();

    }
}

2、线程池(重点)

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

池化技术 程序的运行、本质:占用系统的资源|优化资源的使用==》池化技术 线程池、连接池、内存池、对象池。。。创建、销毁、浪费资源

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

线程池的好处:

  • 1、降低资源的消耗
  • 2、提高响应的的速度
  • 3、方便管理 ==线程复用、可以控制最大并发数,管理线程==

2.1 使用单例

package com.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo1 {
    public static void main(String[] args) {
        ExecutorService threadpool = Executors.newSingleThreadExecutor();//单个线程

        try {
            for (int i = 0; i < 10; i++) {
                //使用线程池之后,使用线程池来创建线程
                threadpool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"ok");
                });

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadpool.shutdown();
        }
    }
}


在这里插入图片描述

2.2、使用固定大小的线程

package com.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo1 {
    public static void main(String[] args) {
//        ExecutorService threadpool = Executors.newSingleThreadExecutor();//单个线程

        ExecutorService threadpool = Executors.newFixedThreadPool(5);//创建一个固定大小的线程池的大小
        try {
            for (int i = 0; i < 10; i++) {
                //使用线程池之后,使用线程池来创建线程
                threadpool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"ok");
                });

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadpool.shutdown();
        }
    }
}

在这里插入图片描述

2.3、缓存线程池

package com.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo1 {
    public static void main(String[] args) {
//        ExecutorService threadpool = Executors.newSingleThreadExecutor();//单个线程

//        ExecutorService threadpool = Executors.newFixedThreadPool(5);//创建一个固定大小的线程池的大小

        ExecutorService threadpool = Executors.newCachedThreadPool();//可伸缩的,遇强则强,遇弱则弱
        try {
            for (int i = 0; i < 10; i++) {
                //使用线程池之后,使用线程池来创建线程
                threadpool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"ok");
                });

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadpool.shutdown();
        }
    }
}

在这里插入图片描述

2.4 七大参数

源码分析 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 本质上是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.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

四种拒绝策略 在这里插入图片描述 1、ThreadPoolExecutor.AbortPolicy() 银行满了,还有人进来,不处理这个人的,抛出异常

2、ThreadPoolExecutor.CallerRunsPolicy() 银行满了,还有人进来,哪来的去哪里

3、ThreadPoolExecutor.DiscardPolicy() 队列满了、不会抛出异常

4、ThreadPoolExecutor.DiscardOldestPolicy() 队列满了、尝试去和最早的竞争,也不会抛出异常

1、cpu密集型,几核,就是几,可以保证CPU的效率最高!!!Runtime.getRuntime().availableProcessors()

2、IO密集型 判断你程序中十分耗IO的线程 程序 15个大型任务,io十分占用资源