前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java服务端两个常见的并发错误

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

作者头像
FunTester
发布2020-02-17 16:08:39
3180
发布2020-02-17 16:08:39
举报
文章被收录于专栏:FunTesterFunTester

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

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

Bean中的请求状态

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

代码如下:

代码语言:javascript
复制
public void handleOrder(Order order) {
   ...
   currentLineItem = order.getLine(0);
   processLineItem();
}
 
private void processLineItem() {
   myService.store(currentLineItem);
}

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

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

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

对象初始化错误

延迟初始化允许:

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

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

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

代码语言:javascript
复制
private LazyService getLazyService() {
   if (lazyService != null) {
      return lazyService;
   }
   LazyService newLazyService = connectToLazyService();
   registerWithServiceRegistry(newLazyService);
   lazyService = newLazyService;
   return newLazyService;
}

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

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

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

代码语言:javascript
复制
    private volatile static Singleton singleton;
    public static Singleton getSingleton() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }

  • 郑重声明:文章首发于公众号“FunTester”,禁止第三方(腾讯云除外)转载、发表。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FunTester 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Bean中的请求状态
  • 对象初始化错误
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档