2013-02-25 21 views
3

我STUDING为1Z0-851 Oracla的Java SE 1.6认证,我看到了这样一个问题:Java类线程安全的方法,考试认证1Z0-851

question 4

任何人都可以解释我这个答案吗?

说我是很正确的,当我这样想: 如果doThings()是静态的只有一个访问可以被时间做出尽管当方法不static各一次TestSeven对象将在同一时间访问doThings修改x值不一致。

我正确地思考这种方式吗?

谢谢。

回答

4

就是这样。目前,如果您创建两个TestSeven实例并从两个不同的线程调用它们的doThings方法,则不能保证x将会增加两次。例如,下面的执行是合法的(T1和T2是两个线程):

T1: current = x //0 
T2: current = x //0 
T1: current++; // 1 
T2: current++; // 1 
T1: x = current; // 1 
T2: x = current; // 1 

所以,你必须调用该方法两次,但X已递增一次。

如果您使该方法为静态,即使您创建了多个实例,只有一个线程能够在给定时刻执行它。

+0

不错!多数民众赞成在我的想法..我可以做一个'同步(TestSeven.class){}'而不是使这个方法也是静态的? – thiagoh 2013-02-25 18:21:42

+0

正确,你可以使用一个同步块,其中锁是类(或另一个任意的静态字段)。 – 2013-02-25 18:23:25

+1

@thiagoh是的,它会达到相同的效果:你可以使用任何静态对象作为锁(TestSeven.class是一种可能性)。 – assylias 2013-02-25 18:23:53

2

它不是线程安全的,因为X范围是“静”,即所有的类实例可以访问它,并且doThings方法是没有的。所以它只在类实例上同步。

因此,尽管使用了synchronized关键字,但可以有两个类实例在同一时间访问x

使方法静态将确保它一次只能调用一次。

2

doThings()方法是一种实例方法,正在读写静态变量x。通过使doThings()为静态,它将在所有实例(类的内部锁,而不是实例)上同步。换句话说,就目前来看,这个方法可以被多个线程同时调用,而使它变为静态将会阻止这个方法。

0

如果x未标记为静态,那么该类将是线程安全的吗?