Java线程之线程池

1、什么是线程池?

                线程池:用来管理线程对象的池子

2、为什要使用线程池?

               1、解决频繁的创建和销毁线程消耗的性能

                2、解决大量创建线程而导致的内存泄露问题

                 注意: 一个线程大约占用内存1M

3、Java中是如何创建线程池

                1、通过工具类完成线程池的创建【Executors】语法简单。但是阿里巴巴不建议使用 

                        3.1、Executors中常用的方法:

                   2、通过线程池类:ThreadPoolExecutor类。语法复杂,但是阿里巴巴建议使用。灵活

 ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(10);
        /**
         * corePoolSize 初始化线程数量
         * maximumPoolSize最大线程数
         * keepAliveTime,线程维持时间
         * TimeUnit unit 时间单位
         * BlockingQueue<Runnable> workQueue 堵塞队列
         *
         */
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 5, 10, TimeUnit.SECONDS,arrayBlockingQueue);
        for (int i = 0; i <4 ; i++) {

            threadPoolExecutor.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"=========");
                }
            });
        }
    }

                                     3.2、ThreadPoolExecutor类中常用的方法

    • voidshutdown()有序关闭线程池,未执行完的任务将继续执行,但不接收新的任务

 以下三种方法是AbstractExecutorService中实现ExecutorService接口中的方法

    • <T> Future<T>submit(Callable<T> task)

      提交值返回任务以执行,并返回代表任务待处理结果的Future。

      Future<?>submit(Runnable task)

      提交一个可运行的任务执行,并返回一个表示该任务的未来。

      <T> Future<T>submit(Runnable task, T result)

      提交一个可运行的任务执行,并返回一个表示该任务的未来。

                                      3.3 方法中Runnable参数的三种写法

                                                   1、创建实现了Runnable接口的类

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i <10 ; i++) {
            System.out.println(Thread.currentThread().getName()+"============"+i);
        }
    }


     public static void main(String[] args) {
       
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        //创建一个类实现Runnable接口重新run方法
        for (int i = 0; i <3 ; i++) {
                executorService.execute(new MyRunnable());
        }
       


    }
}

                                                   2、匿名内部类

 //2、匿名内部类
        for (int i = 0; i <3 ; i++) {
            executorService.execute(new Runnable(){

                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"===============");
                }
            });
        }

                                                   3、lamba表达上      

 //lambda表达式
        for (int i = 0; i <3 ; i++) {
            executorService.execute(()-> System.out.println(Thread.currentThread().getName()+"========="));
        }

                                     3.4 execite和submit方法的区别?

                                                 这两个方法都是用来执行线程任务,但是execute属于Executor类中的方法,而submit属于ExecutorService接口中的方法。而且submit可以执行runnable和callable类型的任务,而execute只能执行Runnable类型的任务。submit执行完Callable任务后有返回结果               

4、 为什么不建议使用Executors来创建线程池

        当使用Executors创建FixedTreadPool和SingleThreadExecutor时它们的构造函数都需要传一个LinkedBlickingQueue对列,这是一个无界阻塞队列,如果使用该线程池执行任务,当任务过多就会不断添加到队列中,任务越多占用的内存就越多,最终可能耗尽内存造成内存溢出(OOM)。

        另外使用Executors来创建线程池不能自定义线程的名字,不利于排查问题。所以一般直接使用ThreadPoolExecutor来定义线程池,这样更灵活

  • 40
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值