The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:
你知道什么是线程安全吗?如果不知道,下面有一个简单的例子。所有类都必须是线程安全的,对吗?并不完全是。有些类必须是线程安全的?再次错了。我认为没有一个类必须是线程安全的,但是所有类都必须提供同步的装饰器。
让我们从一个例子开始(顺便说一句,它是可变的):
你认为呢,它是线程安全的吗?这个术语指的是当多个线程同时使用该类的对象时,它是否会无错误地运行。假设我们有两个线程同时使用同一个对象position
,并在同一时刻调用它的方法increment()
。
我们期望当两个线程都完成时,number
整数应该等于2,因为它们每个线程都会将其增加一次,对吗?然而,很可能这并不会发生。
让我们看看会发生什么。在两个线程中,它们开始时before
都等于0。然后after
将被设置为1。然后,两个线程都会执行this.number = 1
,我们最终得到的是number
中的1,而不是期望的2。看到问题了吗?设计中存在这种缺陷的类不是线程安全的。
最简单、最明显的解决方法是将我们的方法设为synchronized
。这将确保无论有多少个线程同时调用它,它们都会按顺序而不是并行进行:一个线程接着另一个线程。当然,这会花费更长的时间,但它会防止发生那个错误。
保证无论有多少个线程与之交互,都不会出错的类称为线程安全。
现在的问题是:我们是否需要使所有类都具备线程安全性,还是只有部分类需要?看起来让所有类都没有错误会更好,对吧?为什么有人会想要一个在某个时间点可能会出错的对象呢?嗯,并不完全是这样。请记住,这涉及到性能问题;我们很少有多个线程,而且我们总是希望对象运行尽可能快。而线程间同步机制肯定会减慢我们的速度。
我认为正确的方法是拥有两个类。第一个类不是线程安全的,而第二个类是一个同步装饰器,它的样子如下:
现在,当我们需要我们的position
对象是线程安全的时候,我们使用SyncPosition
进行修饰。
当我们需要一个简单的位置时,不需要任何线程安全,我们这样做:
在我看来,使类功能既丰富又线程安全违反了著名的单一职责原则。
顺便说一下,这个问题与防御式编程和验证器的问题非常相似。
Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-27 at 10:38