Java详解使用线程池处理任务方法

 更新时间:2022年05月07日 11:38:33   作者:遇安.112  
java中经常需要用到多线程来处理,我们非常不建议单纯使用继承Thread或者实现Runnable接口的方式来创建线程,那样势必有创建及销毁线程耗费资源、线程上下文切换问题。同时创建过多的线程也可能引发资源耗尽的风险,这个时候引入线程池比较合理,方便线程任务的管理

什么是线程池?

线程池就是一个可以复用线程的技术。

不使用线程池的问题:

如果用户每发起一个请求,后台就创建一个新线程来处理,下次新任务来了又要创建新线程,而创建新线程的开销是很大的,这样会严重影响系统的性能。

线程池常见面试题:

1、临时线程什么时候创建?

新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程。

2、什么时候会开始拒绝任务?

核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始任务拒绝。

1、线程池处理Runnable任务

import java.util.concurrent.*;
public class 多线程_5线程池处理Runnable任务 {
    public static void main(String[] args) {
        //线程池处理Runnable任务
        //创建线程池对象
        /*
         public ThreadPoolExecutor(int corePoolSize,//核心线程数量
                              int maximumPoolSize,//线程池可支持的最大线程数量
                              long keepAliveTime,//临时线程的最大存活时间
                              TimeUnit unit,//指定存活时间的单位(秒,分等)
                              BlockingQueue<Runnable> workQueue,//指定任务队列
                              ThreadFactory threadFactory,//指定用哪个线程工厂创建线程
                              RejectedExecutionHandler handler)//指定线程忙,任务满了的时候,新任务来了怎么办
         */
        ExecutorService pool=new ThreadPoolExecutor(3,5,
                6, TimeUnit.SECONDS,new ArrayBlockingQueue<>(5),
                Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
        //给任务线程池处理
        Runnable r=new MyExe();
        //三个核心线程
        pool.execute(r);
        pool.execute(r);
        pool.execute(r);
        //五个任务队列(不创建临时线程时,会发现只有三个线程,即核心线程量)
        pool.execute(r);
        pool.execute(r);
        pool.execute(r);
        pool.execute(r);
        pool.execute(r);
        //创建临时线程(五个线程,即最大线程量)
        pool.execute(r);
        pool.execute(r);
        //不创建,拒绝策略被触发
       // pool.execute(r);
        //关闭线程池(开发中一般不会使用)
//        pool.shutdownNow();//立即关闭,即使任务没有执行完毕。会丢失任务的!
//        pool.shutdown();//会等待任务全部执行完毕后再关闭(建议使用)
    }
}
class MyExe implements Runnable{
    public void run(){
        for (int i = 1; i <=6 ; i++) {
            System.out.println(Thread.currentThread().getName()+"正在执行:"+i+"次");
        }
        //因为当前案例任务太简单,我们需要创建临时队列需要让三个核心线程忙,五个任务队列排满,所以让线程休眠以增加任务时间
        try {
            System.out.println(Thread.currentThread().getName()+"任务与线程绑定,线程进入了休眠");
            Thread.sleep(1000000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2、线程池处理Callable任务

import java.util.concurrent.*;
public class 多线程_5线程池处理Callable任务 {
    public static void main(String[] args) throws Exception {
        //线程池处理Callable任务
        //创建线程池对象
        /*
         public ThreadPoolExecutor(int corePoolSize,//核心线程数量
                              int maximumPoolSize,//线程池可支持的最大线程数量
                              long keepAliveTime,//临时线程的最大存活时间
                              TimeUnit unit,//指定存活时间的单位(秒,分等)
                              BlockingQueue<Runnable> workQueue,//指定任务队列
                              ThreadFactory threadFactory,//指定用哪个线程工厂创建线程
                              RejectedExecutionHandler handler)//指定线程忙,任务满了的时候,新任务来了怎么办
         */
        ExecutorService pool=new ThreadPoolExecutor(3,5,
                6, TimeUnit.SECONDS,new ArrayBlockingQueue<>(5),
                Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
        //给任务线程池处理
//        Callable c=new MyCallable2(100);
//        pool.submit(c);
       Future<String> f1=pool.submit(new MyCallable2(100));
        Future<String> f2=pool.submit(new MyCallable2(200));
        Future<String> f3=pool.submit(new MyCallable2(300));
        Future<String> f4=pool.submit(new MyCallable2(400));
        Future<String> f5=pool.submit(new MyCallable2(500));
//        String str=f1.get();
//        System.out.println(str);
        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());
        System.out.println(f4.get());
        System.out.println(f5.get());
    }
}
class MyCallable2 implements Callable<String> {
    //                               v(泛型)
    private int n;
    public MyCallable2(int n) {
        this.n = n;
    }
    //重写call方法
    //案例:加法
    public String call() throws Exception {
        int sum = 0;
        for (int i = 1; i <=n; i++) {
            sum += i;
        }
        return Thread.currentThread().getName()+"执行 1-"+n+"的和,结果为:" + sum;
    }
}

到此这篇关于Java详解使用线程池处理任务方法的文章就介绍到这了,更多相关Java线程池内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现的文件过滤代码分享(按后辍过滤)

    Java实现的文件过滤代码分享(按后辍过滤)

    这篇文章主要介绍了Java实现的文件过滤代码分享,本文通过后辍名过滤,代码写简洁,容易看懂,需要的朋友可以参考下
    2014-07-07
  • Spring框架中Bean的各种加载方式详解

    Spring框架中Bean的各种加载方式详解

    这篇文章主要介绍了Spring框架中Bean的各种加载方式详解,在Java中,"Bean"通常指的是由Spring框架管理的对象实例,Spring提供了多种方式来加载Bean,以满足不同的需求和场景,需要的朋友可以参考下
    2023-08-08
  • Java如何在Map中存放重复key

    Java如何在Map中存放重复key

    这篇文章主要介绍了Java如何在Map中存放重复key,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • SpringBoot读取properties配置文件中的数据的三种方法

    SpringBoot读取properties配置文件中的数据的三种方法

    本文主要介绍了SpringBoot读取properties配置文件中的数据的三种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-06-06
  • 教你在JNA中将本地方法映射到JAVA代码中的示例

    教你在JNA中将本地方法映射到JAVA代码中的示例

    对于JNI来说,我们可以使用native关键字来定义本地方法。那么在JNA中有那些在JAVA代码中定义本地方法的方式呢?对JNA本地方法映射JAVA代码的相关知识感兴趣的朋友一起看看吧
    2022-04-04
  • 一文带你深入剖析Java线程池的前世今生

    一文带你深入剖析Java线程池的前世今生

    这篇文章主要带大家介绍了深入剖析一下Java线程池的前世今生,了解线程池的原理以及为什么需要线程池。文中的示例代码讲解详细,需要的可以参考一下
    2022-10-10
  • java高并发下解决AtomicLong性能瓶颈方案LongAdder

    java高并发下解决AtomicLong性能瓶颈方案LongAdder

    这篇文章主要为大家介绍了java高并发下解决AtomicLong性能瓶颈方案LongAdder,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • 深入解析Java的Servlet过滤器的原理及其应用

    深入解析Java的Servlet过滤器的原理及其应用

    这篇文章主要介绍了深入解析Java的Servlet过滤器的原理及应用,Java编写的Servlet通常是一个与网页一起作用于浏览器客户端的程序,需要的朋友可以参考下
    2016-01-01
  • Java使用注解实现防止重复提交实例

    Java使用注解实现防止重复提交实例

    这篇文章主要介绍了Java使用注解实现防止重复提交实例,在一些项目中由于用户误操作,多次点击表单提交按钮,会产生很多次的数据交互,为了解决这一问题,本文使用注解来实现防止重复提交,需要的朋友可以参考下
    2023-07-07
  • Spring注解驱动之@EventListener注解使用方式

    Spring注解驱动之@EventListener注解使用方式

    这篇文章主要介绍了Spring注解驱动之@EventListener注解使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09

最新评论