Java开发手册之并发处理

Java开发手册之并发处理Java开发手册之并发处理

大家好,又见面了,我是你们的朋友全栈君。

  1. 【强制】获取单例对象需要保证线程安全,其中的方法也要保证线程安全。说明:资源驱动类、工具类、单例工厂类都需要注意。
  2. 【强制】创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。
    正例:
public class TimerTaskThread extends Thread {     
 public TimerTaskThread() {        
   super.setName("TimerTaskThread");  
    ... 
     }  
  1. 【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
    说明:使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者 “过度切换”的问题。
  2. 【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
AtomicInteger count = new AtomicInteger(); 
count.addAndGet(1);

Executors返回的线程池对象的弊端如下:
1) FixedThreadPool和SingleThreadPool: 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。
2) CachedThreadPool和ScheduledThreadPool: 允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。
5. 【强制】SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为 static,必须加锁,或者使用DateUtils工具类。
正例:注意线程安全,使用DateUtils。亦推荐如下处理:

private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {       
 @Override        
 protected DateFormat initialValue() {            
 return new SimpleDateFormat("yyyy-MM-dd");       
  }    
};    

说明:如果是JDK8的应用,可以使用Instant代替Date,LocalDateTime代替Calendar, DateTimeFormatter代替SimpleDateFormat,官方给出的解释:simple beautiful strong immutable thread-safe
6. 【强制】高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁。
说明:尽可能使加锁的代码块工作量尽可能的小,避免在锁代码块中调用 RPC 方法。
7. 【强制】对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁。
说明:线程一需要对表A、B、C依次全部加锁后才可以进行更新操作,那么线程二的加锁顺序也必须是A、B、C,否则可能出现死锁。
8. 【强制】并发修改同一记录时,避免更新丢失,需要加锁。要么在应用层加锁,要么在缓存加
锁,要么在数据库层使用乐观锁,使用version作为更新依据。
说明:如果每次访问冲突概率小于20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于3次。
9. 【强制】多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获
抛出的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。
10. 【推荐】使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown 方法,线程执行代码注意catch异常,确保countDown方法被执行到,避免主线程无法执行至await方法,直到超时才返回结果。
说明:注意,子线程抛出异常堆栈,不能在主线程try-catch到。
11. 【推荐】避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一
seed 导致的性能下降。
说明:Random实例包括java.util.Random 的实例或者 Math.random()的方式。
正例:在JDK7之后,可以直接使用API ThreadLocalRandom,而在 JDK7之前,需要编码保证每个线程持有一个实例。
12. 【推荐】在并发场景下,通过双重检查锁(double-checked locking)实现延迟初始化的优化问题隐患(可参考 The “Double-Checked Locking is Broken” Declaration),推荐解决方案中较为简单一种(适用于JDK5及以上版本),将目标属性声明为 volatile型。
反例

class Singleton {  
 private Helper helper = null;  
public Helper getHelper() {  
if (helper == null) synchronized(this) {      
if (helper == null)         
helper = new Helper();    
}      
return helper;  
}  
// other methods and fields...  
}  
  1. 【参考】volatile解决多线程内存不可见问题。对于一写多读,是可以解决变量同步问题,但是如果多写,同样无法解决线程安全问题。如果是count++操作,使用如下类实现:
AtomicInteger count = new AtomicInteger(); 
count.addAndGet(1);

如果是JDK8,推荐使用LongAdder对象,比AtomicLong性能更好(减少乐观锁的重试次数)。
14. 【参考】 HashMap在容量不够进行resize时由于高并发可能出现死链,导致CPU飙升,在开发过程中可以使用其它数据结构或加锁来规避此风险。
15. 【参考】ThreadLocal无法解决共享对象的更新问题,ThreadLocal对象建议使用static
修饰。这个变量是针对一个线程内所有操作共享的,所以设置为静态变量,所有此类实例共享此静态变量 ,也就是说在类第一次被使用时装载,只分配一块存储空间,所有此类的对象(只要是这个线程内定义的)都可以操控这个变量。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/106535.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 运行时错误‘-2147467259(80004005)操作必须使用一个可更新的查询[通俗易懂]

    运行时错误‘-2147467259(80004005)操作必须使用一个可更新的查询[通俗易懂]运行时错误‘-2147467259(80004005)操作必须使用一个可更新的查询昨天晚上一个网友发给我一个酒店客房管理系统,让我帮他看看是什么问题源码拿来一看是网上下载的,数据库是access。

    2022年7月4日
    27
  • 【APP UI 设计模式】(一)APP UI 设计原则和流程

    【APP UI 设计模式】(一)APP UI 设计原则和流程

    2021年12月3日
    61
  • FPGA与CPLD的区别

    FPGA与CPLD的区别CPLD和FPGA两者的区别CPLD和FPGA都是我们经常会用到的器件。有的说有配置芯片的是FPGA,没有的是CPLD;有的说逻辑资源多的是FPGA,少的是CPLD;有的直接就不做区分,把他们都叫做FPGA。那么两者到底有什么区别呢?下面我们就以Altera公司的CPLD和FPGA为例来说说两者的区别。首先我们看一下CPLD的芯片结构,搞清楚CPLD是由哪几部分组成的。下图是MAX系…

    2022年5月4日
    48
  • pve 删除虚拟机「建议收藏」

    qmdestroy100#之后以一下查看虚拟机qmlist100常用命令:qmguestcmd<vmid><command>qmguestexec-status<vmid><pid>qmguestpasswd<vmid><username>[OPTIONS]qmguestexec<vmid>[<extra-args>][OP.

    2022年4月17日
    251
  • Ubuntu安装yum失败

    Ubuntu安装yum失败先看一下虚拟机可以上网;那么联网没有问题;yum-ylistjava*;查看jdk版本;提示yum没有安装;那么先要安装yum;输入rpm-qayum,查看yum的安装情况,rpm也没有安装;输入apt-getinstallyum安装yum,提示权限不足,areyouroot?当前是root用户;在命令前加sudo就对了;sudoapt-getinstallyum;然后提示不能定位yum包;需要先执行apt-getupdate;前面还

    2022年6月16日
    37
  • Flash Cookie【使用Flash Cookie技术在客户端永久保存HTTP Cookie 】(一)

    Flash Cookie【使用Flash Cookie技术在客户端永久保存HTTP Cookie 】(一)前言:  在我负责的一个项目中,为了实现一个特殊的需求,要求在客户端的Cookie中长久保存一份数据,但是我们知道在客户端Cookie里保存数据是不稳定的,因为用户可能随时会清除掉浏览器的Cookie,在这种情况下,一般的解决方案是重新向服务器端发送一个请求,以获得一个新的HTTPCookie数据,并将其保存--就一般的交互需求而言,这是没有问题的。但是,倘若我的需求是:要求恢复到原来的Co

    2022年7月14日
    21

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号