java - 线程安全: Instance of class

标签 java multithreading

下面是实践中的 Java 并发的第一个代码片段。我不明白这个类为什么不是线程安全的?是不是每次线程需要调用 getNext() 方法时,它都会先创建这个类的实例?两个线程可以共享此类的同一个实例(禁止显式共享)吗?

@NotThreadSafe
public class UnsafeSequence {
private int value;
/** Returns a unique value. */
public int getNext() {
return value++;
}
 }

最佳答案

I don't get how this class is not thread safe?

(您现在可能已经找到了答案,但为了完整起见,我将其包含在此处。)

问题出在 value++ 语句上。这是一个由多部分组成的声明。

  1. 读取value的值。
  2. 读取值加一。
  3. 新值存储在value中。

该序列可以由另一个线程混合。假设5。如果两个线程调用 getNext()(在同一个实例上),则当它们完成时,您会期望 value7。但是,如果两个线程在任何线程执行步骤 3 之前都完成了步骤 1 和 2,则它们都会将值 6 写入 value:

  • 线程 1 执行步骤 1 - 读取 5
  • 线程 2 执行步骤 1 - 读取 5
  • 线程 2 执行步骤 2 - 将 5 增加 1
  • 线程 2 执行步骤 3 - 保存值 6
  • 线程 1 执行步骤 2 - 将 5 增加 1
  • 线程 1 执行步骤 3 - 保存值 6

Won't every time a thread needs to call the method getNext(), it would first create instance of this class?

不是每次都这样。那将是一遍又一遍的 new UnsafeSequence().getNext() ,这是没有意义的。但也许这并不完全是你的意思。每个线程都可以有自己的类实例,并对其调用 getNext() 。在这种情况下就没有问题。

Can two threads share same instance of this class (barring explicit share)?

不,必须以某种方式共享实例。但它可能会在你不知情的情况下被分享。例如,某些类可能具有返回 UnsafeSequence 实例的 static 方法。您不知道每次返回的实例是否相同,或者每次调用是否创建一个新实例。 除非这在某处有记录。

<小时/>

API 文档中关于类是否线程安全的讨论是指在线程之间共享实例的情况。如果实例未共享,则可以在多线程应用程序中使用它,只要它可用并仅由一个线程使用即可。

关于java - 线程安全: Instance of class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33459911/

相关文章:

java - Jetty 没有出现在 jcmd 中

java - Java中的延迟队列实现

java - 如何阻止 Apache CXF 将基元转换为对象类型?

java - 避免与 Java 中的静态类重复代码

C++ - Pthread 如何发送值

C++,两个没有锁的编写线程

java - 在数据库中存储 BLOB Spring Hibernate 持久化

Java缓存线程池和线程本地

c# - 如何按顺序运行 C# 线程

c++ - Boost::thread 的可中断线程实现