首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java SCJP/OCPJP

Java SCJP/OCPJP
EN

Stack Overflow用户
提问于 2016-11-11 01:54:18
回答 1查看 173关注 0票数 0

给定:

代码语言:javascript
复制
public class NamedCounter{ 

 private final String name; 

 private int count; 

 public NamedCounter(String name) { this.name = name; } 

 public String getName() { return name; } 

 public void increment() { count++; } 

 public int getCount() { return count; } 

 public void reset() { count = 0; } 

}

应该进行哪三项更改才能使这个类安全地由多个线程使用?(选择三项。)

A.使用synchronized关键字声明reset()

B.使用synchronized关键字声明getName()

C.使用synchronized关键字声明getCount()

D.使用synchronized关键字声明构造函数

E.使用synchronized关键字声明增量()

答案是A,C,E,但我不明白为什么。根据同步关键字仅用于操作操作。那么为什么要回答C呢?

这个问题来自SCJP转储。

EN

回答 1

Stack Overflow用户

发布于 2016-11-18 12:49:15

JVM使用synchronized关键字来告诉它何时需要使变量的内容跨线程可见。在上面的示例中,不仅增量方法是不安全的(后增量操作符需要多个步骤才能执行,因此在增量执行过程中另一个线程可能会干扰它),而且所有接触计数变量的方法--增量、重置和getCount --都需要使用synchronized关键字来指示可以在另一个线程中更改计数变量。否则,JVM可以执行诸如缓存值或完全消除字节码之类的优化,因为它可以自由地推断代码,而无需考虑多线程访问的可能性。

这里有synchronized的替代方案;例如,AtomicInteger也可以工作,使用它进行计数将确保值将自动更改,并以所有线程都可见的方式访问。但由于问题的措辞,答案A、C和E都是必要的。

答案D是错误的,因为声明一个构造函数为synchronized不是有效的语法,如果它是有效的,它将不会为您完成任何事情。同步防止跨线程共享,但构造函数调用不共享任何内容,因此没有什么需要保护的。

答案B是错误的,因为名称是作为构造函数参数传入并分配给最终实例成员的不可变对象;由于它是安全发布的,不能更改,因此同步是不必要的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40534095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档