ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java服务端两个常见的并发错误

2020-01-27 13:01:36  阅读:154  来源: 互联网

标签:singleton Java 单例 对象 并发 测试 服务端 currentLineItem


理想情况来讲,开发在开始编写代码之前就应该讲并发情况考虑进去,但是大多数实际情况确是,开发压根不会考虑高并发情况下的业务问题。主要原因还是因为业务极难遇到高并发的情况。

下面列举两个比较常见的后端编码中常见的并发BUG:

Bean中的请求状态

在Java应用程序中,server,controller,处理程序和存储库通常是单例的。它们是在应用启动时创建的,然后请求通常通过多个线程传递给它们。

代码如下:

public void handleOrder(Order order) {
   ...
   currentLineItem = order.getLine(0);
   processLineItem();
}
 
private void processLineItem() {
   myService.store(currentLineItem);
}

这违反了两个原则:线程安全和有意义的对象状态。这里处理一个order对象的时候只是处理了其中一个的currentLineItem,先是赋值给了当前类对象的属性,然后去处理这个currentLineItem对象,但是如果多个线程同时请求到当前的类单例对象,那么赋值和处理对象中间会发生第二次赋值,此时再去处理currentLineItem对象很可能已经不是之前order对象的currentLineItem

如果将请求的每个属性放入该请求的接收者中,那么将有两个风险:

  • 在多线程执行中的请求之间出错
  • 如果事情没有完全处理完,则在单线程的请求之间出错

对象初始化错误

延迟初始化允许:

由于以下原因,启动速度更快

  • 必要时及时加载资源
  • 如果不需要,则不加载资源(例如,无服务器Lambda,在其生命周期中可能永远不会被要求执行特定的代码路径)
  • 加载优先活动资源

虽然如此,但是,如下代码可能会发生错误:

private LazyService getLazyService() {
   if (lazyService != null) {
      return lazyService;
   }
   LazyService newLazyService = connectToLazyService();
   registerWithServiceRegistry(newLazyService);
   lazyService = newLazyService;
   return newLazyService;
}

尽管它可以工作,但并发调用很可能出错。在示例中:

  • 在并发调用中,发生了多个延迟加载
  • 如果发生多个延迟加载,则可能两个对象在内存中的停留时间超长或者永远存在
  • 如果这是单例,初始化过程中的多余对象可能会获取到唯一的资源导致无法正常工作

为了正确进行单例初始化,您应该使用双重检查锁定或使用框架,甚至使用基于static字段的简单Java单例初始化,如下:

    private volatile static Singleton singleton;
    public static Singleton getSingleton() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }

  • 郑重声明:文章首发于公众号“FunTester”,禁止第三方(腾讯云除外)转载、发表。

技术类文章精选

非技术文章精选

标签:singleton,Java,单例,对象,并发,测试,服务端,currentLineItem
来源: https://www.cnblogs.com/FunTester/p/12235746.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有