0

假设我有以下代码作为 Web 服务的一部分运行。代码必须是线程安全的,例如没有其他 Web 服务调用可以更改另一个实例中的变量。此代码是否满足此要求?

public class ExampleClass {

   public static String abc = "000";
   public static ArrayList<String> myList = new ArrayList();

   public static synchronized final void clearList(){
   mylist.clear();
   } 
   public static synchronized final void addToList(String listItem){
   myList.add(listItem);
   }

   ...

   more static synchronized methods...

}

我继承了这段代码,需要进行最少量的更改以确保它是同步的。

非常感谢您的回答。

[编辑]为了澄清一点。执行此代码时会调用 Web 服务,它正在使用“abc”和“myList”变量,例如更改它们。与此同时,另一个 Web 服务调用进来,它也将开始使用这些变量。然而,这两个单独的请求应该有自己的“abc”和“myList”变量,例如它们不能在它们之间共享这些变量,否则结果将是错误的。

4

4 回答 4

3

不,你的String abcArrayList myList可以被另一个班级清楚地访问。制作它们private(最好是非static)。

于 2013-02-27T16:44:24.487 回答
2

[编辑:附录]

线程安全只是一个表述,而不是一个绝对的术语。除非你定义你的意思,否则很难提供帮助。

例如:您没有描述如何访问“abc”以及您的期望是什么。例如,如果您要求对 abc 和列表的更改是原子的,那么您需要将访问它们的代码包装到单个同步块中。如果“abc”永远不会改变,那么你不需要添加任何东西来使它成为线程安全的。如果是这样,您需要将所有修改并读取到同步块中(否则您将遇到令人讨厌的可见性问题)。如果只有一个线程对 abc 进行更改,那么将其设置为 volatile 应该没问题。

这两个问题是:

  • myList 是公开的,因此很难对使用它的代码做出任何保证甚至假设。如果你把它设为私有,你至少只需要担心你自己的方法。您可能想跳过方法的同步并直接转到: myList = Collections.synchronizedList(new ArrayList()); 这样所有方法都将在 myList 对象上同步;如果您决定这样做,则必须将 myList 设为最终版本(以便没有人可以将其切换为非同步版本);
  • 您的描述:“没有其他 Web 服务调用可以更改另一个实例中的变量”与线程安全无关。任何人都可以更改 myList 中的任何内容,因为您提供了方便的方法(公共静态方法)。此外,ExampleClass 的所有实例共享 myList,并且它们修改单个实例。关键是更改将是线程安全的。
于 2013-02-27T16:52:45.467 回答
1

变量是公开的,所以没有。将它们设为私有。如果您有任何返回列表对象的方法,则需要更改它们以防御性地复制列表。

于 2013-02-27T16:49:02.003 回答
0

如果可以,请使用同步的集合。

于 2013-02-27T16:58:59.267 回答