• 4种常用线程池介绍


    1、线程池的优势

    (1)、降低系统资源消耗,通过重用已存在的线程,降低线程创建和销毁造成的消耗;
    (2)、提高系统响应速度,当有任务到达时,通过复用已存在的线程,无需等待新线程的创建便能立即执行;
    (3)方便线程并发数的管控。因为线程若是无限制的创建,可能会导致内存占用过多而产生OOM,并且会造成cpu过度切换(cpu切换线程是有时间成本的(需要保持当前执行线程的现场,并恢复要执行线程的现场))。
    (4)提供更强大的功能,延时定时线程池。

    2、线程池的工作机制

             2.1 在线程池的编程模式下,任务是提交给整个线程池,而不是直接提交给某个线程,线程池在拿到任务后,就在内部寻找是否有空闲的线程,如果有,则将任务交给某个空闲的线程。

             2.1 一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。

    2、java中提供的线程池

    Executors类提供了4种不同的线程池:newCachedThreadPool, newFixedThreadPool, newScheduledThreadPool, newSingleThreadExecutor

    1、newCachedThreadPool:用来创建一个可以无限扩大的线程池,适用于负载较轻的场景,执行短期异步任务。(可以使得任务快速得到执行,因为任务时间执行短,可以很快结束,也不会造成cpu过度切换)

    2、newFixedThreadPool:创建一个固定大小的线程池,因为采用无界的阻塞队列,所以实际线程数量永远不会变化,适用于负载较重的场景,对当前线程数量进行限制。(保证线程数可控,不会造成线程过多,导致系统负载更为严重)

    3、newSingleThreadExecutor:创建一个单线程的线程池,适用于需要保证顺序执行各个任务。

    4、newScheduledThreadPool:适用于执行延时或者周期性任务。

    newCachedThreadPool:

    package executors;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class NewCachedThreadTest {
        public static void main(String[] args) {
            // 创建可缓存线程池
            ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
            // 执行execute表示创建了线程,类似start
            for (int i = 0; i < 10; i++) {
                 int index = i;
                newCachedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        
                        /*
                         * try { Thread.sleep(300); } catch (InterruptedException e) {
                         * 
                         * e.printStackTrace(); }
                         */
                         
                        System.out.println(Thread.currentThread().getName() + "---" + index);
                        
                        //if(index==9) { newCachedThreadPool.shutdown(); }
                         
                    }
                });
                
    
            }
        }
    }

    执行结果:

     newFixedThreadPool线程池:

    package executors;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class NewFixedThreadPoolTest {
      public static void main(String[] args) {
          //newFixedThreadPool 每次最多我就只能执行10个,其他线程等待
        ExecutorService newFixedThreadPool=  Executors.newFixedThreadPool(10);
         for(int i=0;i<1888888880;i++) {
             int index=i;
             newFixedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"---------"+index);
                }
            });
         }
      }
    }

    执行结果:

     newScheduledThreadPool类:

    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    public class NewScheduledThreadPoolTest {
         public static void main(String[] args) {
             //线程池大小
    ScheduledExecutorService newScheduledThreadPool=    Executors.newScheduledThreadPool(5);
        //scheduled执行定时任务线程
    //for(int i=0;i<10;i++) {
        newScheduledThreadPool.schedule(new Runnable() {
            @Override
            public void run() {
                
                System.out.println("我是3秒后执行------");
            }
        }, 3,TimeUnit.SECONDS);
        }
         }
    //}

     newSingleThreadExecutor类:

    package executors;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class NewSingleThreadExecutorTest {
        public static void main(String[] args) {
       ExecutorService    newSingleThreadExecutor= Executors.newSingleThreadExecutor();
       for(int i=0;i<10;i++) {
           int index=i;
           newSingleThreadExecutor.execute(new Runnable() {
               @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"-----"+index);
                
            }
           });
       }
        }}

    执行结果:

    可参考:https://www.cnblogs.com/jiawen010/p/11855768.html

                  https://www.jianshu.com/p/7726c70cdc40



  • 相关阅读:
    如何让nacos中服务注册的ip是自定义的网段ip ( docker swarm )
    docker swarm集群节点打标签
    mysql 8 设置大小写不敏感
    mysql 8 安装&账户权限控制
    I/O(输入/输出)---序列化与反序列化
    I/O(输入/输出)---字节流与字符流
    I/O(输入/输出)---File类
    转发与重定向的区别
    application的使用(实现计数器)
    HTML的相关路径与绝对路径的问题---通过网络搜索整理
  • 原文地址:https://www.cnblogs.com/zouhong/p/12891932.html
Copyright © 2020-2023  润新知