同步Java方法

时间:2013-02-27 16:42:18

标签: java synchronization

假设我将以下代码作为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 个答案:

答案 0 :(得分:3)

没有。您可以清楚地访问其他班级String abcArrayList myList。让他们private(最好是非static)。

答案 1 :(得分:2)

[编辑:附录]

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

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

这两个问题是:

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

如果可以,请使用synchronized collections