Java高并发(八)——Thread pool 如何创建及常见并行模式

       在前边 Java高并发(四)——ThreadPool,线程复用 中我们学习了ThreadPool,但是在那篇中我们在create Thread pool的时候,由于我安装了阿里的开发规范插件,一直在警告我。这篇我们先看下警告,然后再看下并行开发中常见的模式。

       一,如何更合理的创建ThreadPool:

       1,警告:手动创建线程池,效果会更好哦!

//1,这样创建线程
ExecutorService es = Executors.newFixedThreadPool(size);
/**
*
阿里警告全文:
线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors各个方法的弊端:
1)newFixedThreadPool和newSingleThreadExecutor:
  主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。
2)newCachedThreadPool和newScheduledThreadPool:
  主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。
            
Positive example 1:
    //org.apache.commons.lang3.concurrent.BasicThreadFactory
    ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
        new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());
       
        
            
Positive example 2:
    ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
        .setNameFormat("demo-pool-%d").build();

    //Common Thread Pool
    ExecutorService pool = new ThreadPoolExecutor(5, 200,
         0L, TimeUnit.MILLISECONDS,
         new LinkedBlockingQueue(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());

    pool.execute(()-> System.out.println(Thread.currentThread().getName()));
    pool.shutdown();//gracefully shutdown
       
        
            
Positive example 3:
    
        
        
        

    
        
            
        
    
    //in code
    userThreadPool.execute(thread);
**/       

       2,警告:要使用带有ThreadFactory参数的ThreadPoolExecutor构造方法哦,这样你就可以方便的设置线程名字啦。

//2,这样创建线程
ExecutorService executorService = new ThreadPoolExecutor(size,size,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue());

/**
 *
创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。创建线程池的时候请使用带ThreadFactory的构造函数,并且提供自定义ThreadFactory实现或者使用第三方实现。 
            
    ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
    .setNameFormat("demo-pool-%d").build();
    ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1,
    0L, TimeUnit.MILLISECONDS,
    new LinkedBlockingQueue(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());

    singleThreadPool.execute(()-> System.out.println(Thread.currentThread().getName()));
    singleThreadPool.shutdown();
    
        
            
    public class TimerTaskThread extends Thread {
        public TimerTaskThread(){
        super.setName("TimerTaskThread"); …
    }
**/

       二,多线程常见的并行模式:

并行模式
1,单例模式 无论懒汉模式、恶汉模式,单例模式都需要多线程并发的场景下,保证单个对象的创建,这里可以阅读:https://www.cnblogs.com/zhaoyan001/p/6365064.html
2,不变模式

一种不改变对象,依靠对象的不变性,确保其在多线程并发场景下内部状态的一致性正确性。

通过:a,去除setter方法及修改自身属性的方法;

           b,将所有属性设置为私有,并用final标记,确保其不可修改;

           c,确保没有子类可以重载修改它的行为;

           d,有一个可以创建完整对象的构造函数。

例如:元数据的包装类,String、Boolean、Byte、Integer等.

3,生产者-消费者模式 两类线程通过共享内存缓冲区进行通信,进而达到两类线程的解耦,相互独立,只和共享内存缓冲区剩余空间及存储资源有关。这里可以阅读:https://www.cnblogs.com/chentingk/p/6497107.html
4,Future模式 多线程结果异步调用,提高性能,这里不再赘述,看 Java高并发(七)——Future模式
5,并行流水线 通过将任务拆解为多个步骤,用不同的线程处理不同的步骤,像现实生活中的生产流水线一样。例如数据分析:可以2个线程收集数据,5个线程分析数据、2个线程预警有问题数据……
6,并行搜索 将搜索范围进行有效的拆分,使用多个线程,搜索不同的范围,一个线程搜索到结果即可返回停止。
7,并行排序 将排序的任务想办法如何分割,然后使用多线程进行处理不同任务。其实挺难的,不过是一种思路,可以考虑,这里可以阅读(冒泡排序中的奇偶交换排序):https://blog.csdn.net/qq_37142346/article/details/79573440
8,并行算法 例如当今比较火的AI,如何将算法在高效的处理上实现并行处理,将又一次提高性能。例如庞大矩阵的四则运算等,这里还需要更多的学习,提出一种思路而已。
9,网络多线程 NIO,Reactor模式等。东西比较多,看我的Netty系列即可。Netty将多线程运用的非常棒。

       好,这里进行了前边文章的补充,和一些多线程使用中一些模式一些思路的小结,在我们开发编码,我们可以参考,善于站在巨人的肩膀上,善于思考,善于将前人的东西转化为自己的。继续……

你可能感兴趣的:(学习,Java,高并发多线程,Java高并发——多线程)