我所了解的线程池

149 阅读2分钟

1.最简单的线程的使用

  new Thread() {
            @Override
            public void run() {
                // 业务逻辑
            }
        }.start();

但这确存在着很多问题:

1、首先频繁的创建、销毁对象是一个很消耗性能的事情;

2、如果用户量比较大,导致占用过多的资源,可能会导致我们的服务由于资源不足而宕机;

综上,在实际的开发中,这种操作十分不可取。

2.线程池的优点及作用

  1. 提升系统的性能以及使用率,减少对象的创建与销毁。

  2. 可以控制线程数,有效的提升服务器的使用资源,避免由于资源不足而发生宕机等问题。

3.线程池的四种使用方式

3.1newCachedThreadPool

如果线程池中的线程数量过大,它可以有效的回收多余的线程,如果线程数不足,那么它可以创建新的线程,线程池中的线程数不受限制

缺点:当业务处理时间过长时,会自动的创建线程进行执行其他代码,不可控。

  ExecutorService executor = Executors.newCachedThreadPool();

        for (int i = 0; i < 5; i++) {

            final int index = i;

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            executor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "  " + index);
                }
            });
        }

3.2 newFixedThreadPool

可以自动控制线程池中的线程数,避免不必要的性能消耗。

 ExecutorService executor = Executors.newFixedThreadPool(5);  //设置线程池最大容量

        for (int i = 0; i < 10; i++) {

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            final int index = i;

            executor.execute(() -> {
                try {
                    Thread.sleep(2 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "  " + index);
            });
        }
        executor.shutdown();

3.3 newScheduledThreadPool

  1. 该线程池支持定时,以及周期性的任务执行。
  2. 如果业务执行时间结束,但是线程池设置的间隔时间还没到,不会继续进行,会进行等待。
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); //初始化线程池中的线程个数
        executor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                long start = new Date().getTime();
                System.out.println("scheduleAtFixedRate 开始执行时间:" +
                        DateFormat.getTimeInstance().format(new Date()));
                try {
                    Thread.sleep(1000);  //业务执行时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                long end = new Date().getTime();
                System.out.println("scheduleAtFixedRate 执行花费时间=" + (end - start) / 1000 + "m");
                System.out.println("scheduleAtFixedRate 执行完成时间:" + DateFormat.getTimeInstance().format(new Date()));
                System.out.println("======================================");
            }
        }, 1, 5, TimeUnit.SECONDS); //1 延迟多久开始进行; 2 时间间隔

3.4 newSingleThreadExecutor

单线程池,至始至终都由一个线程来执行。

 ExecutorService executor = Executors.newSingleThreadExecutor();

        for (int i = 0; i < 5; i++) {
            final int index = i;
            executor.execute(() -> {
                try {
                    Thread.sleep(2 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "   " + index);
            });
        }
        executor.shutdown();