美文网首页
阿里编程规范--多线程处理

阿里编程规范--多线程处理

作者: aix91 | 来源:发表于2018-09-17 20:01 被阅读0次

    1. 线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

    1)FixedThreadPool 和 SingleThreadPool: 允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。

    2)CachedThreadPool 和 ScheduledThreadPool: 允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

    图一:Executors 下创建 fixed thread pool

    从图一中我们可以看出,Executors.newFixedThreadPool  指定了线程的数量,但是由于使用的LinkedBlockingQueue,由于没有指定其容量大小,LinkedBlockingQueue会默认一个类似无限大小的容量(Integer.MAX_VALUE);如果生产者的速度一旦大于消费者的速度,也许还没有等到队列满阻塞产生,系统内存就有可能已被消耗殆尽了。

    图二:Executors 下创建 cached thread pool

    图二中,我们可以看出,Executors.newCachedThreadPool 并没有限定线程的数量

    2. SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为 static,必须加锁,或者使用 DateUtils 工具类。

    先来看看,怎么不安全了。

    图三:线程不安全的simpleDateFormat 代码 图四:线程不安全的simpleDateFormat

    可以看到,在多线程的环境下,simpleDateFormat总是会出错。为什么SimpleDateFormat是不安全的?

    图三:SimpleDateFormat  部分源码

    SimpleDateFormat不安全的主要原因就是,它包含了一个calendar的变量。该变量主要用于存储与日期有关的数据。但是在上图的parse方法中,在每establish一个calendar的时候,首先会清除原先的calendar,然后再来set新的。那么问题来了,如果有多个线程(thread1,thread2,这两个线程是共用一个calendar引用的),thread1准备返回新生成的calendar,但此时thread2 将calendar clear了,这样就会出现错误。

    如何避免线程不安全呢?

    1. 使用ThreadLocal 为每一个线程单独分配一个SimpleDateFormat. 如下图所示

    图四:LocalThread 方式解决SimpleFormatDate线程不安全

    2. 使用LocalDate 和DateTimeFormatter

    图五:DateTimeFormatter 解决线程不安全问题

    相关文章

      网友评论

          本文标题:阿里编程规范--多线程处理

          本文链接:https://www.haomeiwen.com/subject/hkdbgftx.html