ICode9

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

java – 更新/写入静态变量的最佳实践?

2019-05-15 20:00:14  阅读:818  来源: 互联网

标签:java static findbugs


我有一个显示部门文档的项目.我将所有文档(从数据库中获取)存储在静态arrayList中.每隔X小时,我就根据数据库中的新doc(如果有的话)重建了arrayList.还有一个静态变量来控制重建该数组,在执行重建任务的方法中设置和取消设置.每个访问服务器的Web浏览器都将创建此类的实例,但doc arrayList和该控件变量在所有类实例之间共享.

Find-Bugs工具抱怨“从实例方法someClassMethod写入静态字段someArrayName和someVariableName”.似乎这不是好事(让类实例方法写入静态字段).有没有人有好的建议如何解决这个问题?谢谢.

最佳答案:

FindBugs bug descriptions

ST: Write to static field from instance method (ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD)

This instance method writes to a static field. This is tricky to get correct if multiple instances are being manipulated, and generally bad practice.

除了并发问题之外,它意味着JVM中的所有实例都在访问相同的数据,并且不允许两个单独的实例组.如果您有一个单独的“manager”对象并将其作为构造函数参数或至少作为setManager()方法参数传递给每个实例,那会更好.

至于并发问题:如果你必须使用静态字段,你的静态字段应该是最终的;显式同步很难. (如果你正在初始化非最终静态字段,还有一些棘手的方面,除了我对Java的了解,但我认为我已经在Java Puzzlers书中看到过它们.)至少有三种方法可以解决这个问题(警告,未经测试的代码如下,在使用前先检查):

>使用线程安全的集合,例如Collections.synchronizedList包裹在未以任何其他方式访问的列表中.

static final List<Item> items = createThreadSafeCollection();


static List<Item> createThreadSafeCollection()
{
   return Collections.synchronizedList(new ArrayList());
}

然后当你从一个实例替换这个集合时:

List<Item> newItems = getNewListFromSomewhere();
items.clear();
items.add(newItems);

这个问题是,如果两个实例同时执行此序列,您可以得到:

Instance1:items.clear();
Instance2:items.clear();
Instance1:items.addAll(newItems);
Instance2:items.addAll(newItems);

并获得一个不符合所需类不变量的列表,即在静态列表中有两组newItems.因此,如果要将整个列表清除为一步,并将第二步添加为项,则此方法不起作用. (但是,如果您的实例只需要添加一个项目,那么items.add(newItem)可以安全地从每个实例中使用.)
>同步对集合的访问.

你需要一个明确的同步机制.同步方法不起作用,因为它们在“this”上同步,这在实例之间不常见.你可以使用:

static final private Object lock = new Object();
static volatile private List<Item> list;
// technically "list" doesn't need to be final if you
// make sure you synchronize properly around unit operations.


static void setList(List<Item> newList)
{
  synchronized(lock)
  {
      list = newList;
  }
}

>使用AtomicReference

static final private AtomicReference<List<Item>> list;


static void setList(List<Item> newList)
{
  list.set(newList);
}

标签:java,static,findbugs
来源: https://codeday.me/bug/20190515/1110011.html

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

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

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

ICode9版权所有