线程池的使用

线程使用存在的问题

  • 如果并发的线程数量很多, 并且每个线程都是执行一个时间很短的任务就结束了, 这样频繁创建线程就会大大降低系统的效率, 因为频繁创建线程和销毁线程需要时间
  • 如果大量线程在执行, 会涉及到线程间上下文的切换, 会极大的消耗CPU运算资源

线程池

  • 其实就是一个容纳多个线程的容器, 其中的线程可以反复使用, 省去了频繁创建线程对象的操作, 无需反复创建线程而消耗过多资源

线程池使用大致流程

  • 创建线程池指定线程开启的数量
  • 提交任务给线程池, 线程池中的线程就会获取任务, 进行处理任务
  • 线程处理完任务, 不会销毁, 而是返回到线程池中, 等待下一个任务执行
  • 如果线程池中的所有线程都被占用, 提交的任务, 只能等待线程池中的线程处理完当前任务

使用线程池的好处

  • 降低资源消耗 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务
  • 提高响应速度 当任务到达时, 任务可以不需要等待线程创建 , 就能立即执行
  • 提高线程的可管理性 可以根据系统的承受能力, 调整线程池中工作线线程的数目, 防止因为消耗过多的内存, 服务器死机 (每个线程需要大约1MB内存, 线程开的越多, 消耗的内存也就越大, 最后死机)

线程池处理Runnable任务

  • 创建线程池
    • java.util.concurrent.ExecutorService 是线程池接口类型, 使用时我们不需自己实现, JDK已经帮我们实现好了, 获取线程池我们使用工具类java.util.concurrent.Executors的静态方法:
    • public static ExecutorService newFixedThreadPool (int num) 指定线程池最大线程池数量获取线程池
  • 提交任务
    • Future submit(Callable task)
    • Future<?> submit(Runnable task)
  • 关闭线程池方法(一般不使用关闭方法,除非后期不用或者很长时间都不用,就可以关闭)
    • void shutdown() 启动一次顺序关闭, 执行以前提交的任务, 但不接受新任务
public class Test1 {
    public static void main(String[] args) {
        // 获取线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(3);

        // 给线程池提交任务
        threadPool.submit(new Student("p1"));
        threadPool.submit(new Student("p2"));
        threadPool.submit(new Student("p3"));
        threadPool.submit(new Student("p4"));
        threadPool.submit(new Student("p5"));

        // 关闭线程池
        threadPool.shutdown();
    }
}

class Student implements Runnable {
    private String name;

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

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "正在教" + name + "游泳");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

线程池处理Callable任务

public class Test2 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(5);

        // 为线程池提交任务
        Future<Integer> future = threadPool.submit(new Calc(100));
        Integer result = future.get();
        System.out.println(result);
    }
}

class Calc implements Callable<Integer> {
    private int n;

    public Calc(int n) {
        this.n = n;
    }

    @Override
    public Integer call(){
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            sum += i;
        }
        return sum;
    }
}

自定义创建线程池对象

  • ThreadPoolExecutor线程池类

      public ThreadPoolExecutor(
                          int corePoolSize,                   -- 核心线程数量
                          int maximumPoolSize,                -- 最大线程数量
                          long keepAliveTime,                 -- 临时线程存活时间
                          TimeUnit unit,                      -- 临时线程存活时间单位
                          BlockingQueue<Runnable> workQueue,  -- 阻塞队列
                          ThreadFactory threadFactory,        -- 创建线程的方式
                          RejectedExecutionHandler handler    -- 取舍模式
                          )
    
public class Test3 {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                3,                          // 核心线程数量
                10,                                     // 最大线程数量
                60,                                     // 临时线程存活时间
                TimeUnit.SECONDS,                       // 临时线程存活时间单位
                new ArrayBlockingQueue<>(20),   // 阻塞队列
                Executors.defaultThreadFactory(),       // 创建线程的方式
                new ThreadPoolExecutor.AbortPolicy()    // 拒绝策略
        );
        for (int i = 0; i < 40; i++) {
            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("任务执行");
                }
            });
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值