java 数据库 update 变量_java – 更新/写入静态变量的最佳实践?

在Java项目中,使用静态ArrayList存储数据库文档,并有一个静态变量控制重建操作。Find-Bugs工具警告写入静态字段可能引发并发问题和不良实践。解决方案包括使用线程安全的集合、同步访问或AtomicReference。建议避免多个实例共享静态数据,考虑使用单例的“manager”对象来管理这些资源。
摘要由CSDN通过智能技术生成

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

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

最佳答案:

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 items = createThreadSafeCollection();

static List createThreadSafeCollection()

{

return Collections.synchronizedList(new ArrayList());

}

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

List 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 list;

// technically "list" doesn't need to be final if you

// make sure you synchronize properly around unit operations.

static void setList(List newList)

{

synchronized(lock)

{

list = newList;

}

}

>使用AtomicReference

static final private AtomicReference> list;

static void setList(List newList)

{

list.set(newList);

}

标签:java,static,findbugs

来源: https://codeday.me/bug/20190515/1110011.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值