2.1. What is Thread Safety?(什么是线程安全)

2.1. What is Thread Safety?(什么是线程安全)
Defining thread safety is surprisingly tricky. The more formal attempts are so complicated as to offer little practical guidance or intuitive understanding, and the rest are informal descriptions that can seem downright circular. A quick Google search turns up numerous "definitions" like these:
线程安全的定义出奇的复杂。比较严格的定义有可能会过于复杂以至于难以理解并且没有实际的价值。而一些非正式的描述则有可能会陷入循环论证的陷阱。从google中,我们搜索到了这样的描述:
. . . can be called from multiple program threads without unwanted interactions between the threads.
即使被多个线程调用,线程间也不会出现意料之外的交互时序。
. . .may be called by more than one thread at a time without requiring any other action on the caller's part.
可以同时被多个线程调用,而要求调用方其他任何的动作。
Given definitions like these, it's no wonder we find thread safety confusing! They sound suspiciously like "a class is thread-safe if it can be used safely from multiple threads." You can't really argue with such a statement, but it doesn't offer much practical help either. How do we tell a thread-safe class from an unsafe one? What do we even mean by "safe"?
看到上述的定义后,我们对线程安全的定义可能反而更加迷惑。这就好像说“一个类是线程安全的就是我们可以在多线程中放心的使用它们”。你的确从这样的话中找不出瑕疵,但是这样的定义也的确不会让你明白任何事情。我们如何区分一个类是线程安全的,还是不安全的。甚至,什么是“安全”?
At the heart of any reasonable definition of thread safety is the concept of correctness. If our definition of thread safety is fuzzy, it is because we lack a clear definition of correctness.
任何针对线程安全的合理定义中,正确性都应该是核心内容。如果我们关于线程安全的定义是模糊的,那通常是因为我们缺少了对正确性的定义。
Correctness means that a class conforms to its specification. A good specification defines invariants constraining an object's state and post conditions describing the effects of its operations. Since we often don't write adequate specifications for our classes, how can we possibly know they are correct? We can't, but that doesn't stop us from using them anyway once we've convinced ourselves that "the code works". This "code confidence" is about as close as many of us get to correctness, so let's just assume that single-threaded correctness is something that "we know it when we see it". Having optimistically defined "correctness" as something that can be recognized, we can now define thread safety in a somewhat less circular way: a class is thread-safe when it continues to behave correctly when accessed from multiple threads.
正确性意味着一个类实现了它的类规范说明中的行为。好的规范会定义常量来约束对象的状态并且提供使用其方法的条件。对于我们开发的类,我们经常会无法提供足够的文档来描述他们,那么,我们怎样能够知道如何使用它们才是正确的?答案是,我们不能。但是无论如何,我们仍将会使用这些代码,因为我们确信他们是可以工作的。这种“代码自信”在大部分情况下,所以我们可以大胆的宣称,单线程的安全性就是“所见即所得”。这样我们就可以在很大程度上避免“循环论证”地给出一个线程安全的定义了:线程安全就是一个类被多线程访问的时候可以持续的保持正确的行为。
A class is thread-safe if it behaves correctly when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, and with no additional synchronization or other coordination on the part of the calling code.
线程安全就是一个类被多线程访问的时候可以持续的保持正确的行为。而不需要考虑由运行时环境决定线程的时序和交叉。并且不需要在其调用方附加同步机制或其他条件。

Since any single-threaded program is also a valid multithreaded program, it cannot be thread-safe if it is not even correct in a single-threaded environment. [2] If an object is correctly implemented, no sequence of operations calls to public methods and reads or writes of public fields should be able to violate any of its invariants or post conditions. No set of operations performed sequentially or concurrently on instances of a thread-safe class can cause an instance to be in an invalid state.
[2] If the loose use of "correctness" here bothers you, you may prefer to think of a thread-safe class as one that is no more broken in a concurrent environment than in a single-threaded environment.
任何单线程程序都可以转变成一个正确的多线程程序,因为如果一个程序如果不是线程安全的,那么他在单线程环境中也不会是线程安全的。如果一个对象被正确的实现的话,那么对其public方法和public域的任何操作时序都不会破坏他的不变性和post conditions。也不会有任何操作能够把线程安全的类变成不合法的状态。
如果对“正确性”这个字眼的频繁使用会让你觉得困扰的话,你可以认为一个线程安全的类既不会在单线程环境中被破坏,也不会在多线程环境中被破坏。
Thread-safe classes encapsulate any needed synchronization so that clients need not provide their own.
线程安全的类在其内部封装了所有需要的同步机制所以客户端不需要自己来提供。

2.1.1. Example: A Stateless Servlet(实例:无状态的servlet)
In Chapter 1, we listed a number of frameworks that create threads and call your components from those threads, leaving you with the responsibility of making your components thread-safe. Very often, thread-safety requirements stem not from a decision to use threads directly but from a decision to use a facility like the Servlets framework. We're going to develop a simple example a servlet-based factorization service and slowly extend it to add features while preserving its thread safety.
在第一章中,我们列举了很多可能会创建线程来回调你的应用组件的框架,这些框架把维护线程安全的责任留给了你的应用组件。在很多情况下,线程安全的需求不是来源于你自身的决定而是来源于你所使用的框架的需求,比如Servlets框架就是这样。在保证线程安全的前提下,我们将会开发一个基于servlet的服务,并且慢慢加入一些有特色的东西。
Listing 2.1 shows our simple factorization servlet. It unpacks the number to be factored from the servlet request, factors it, and packages the results into the servlet response.
表2.1向我们展现了一个简单的servlet的元素。它把请求解包、把请求因子化、把结果打包进入servlet响应。
Listing 2.1. A Stateless Servlet.(无状态的servlet)
@ThreadSafe
public class StatelessFactorizer implements Servlet {
public void service(ServletRequest req, ServletResponse resp) {
BigInteger i = extractFromRequest(req);
BigInteger[] factors = factor(i);
encodeIntoResponse(resp, factors);
}
}

Stateless Factorizer is, like most servlets, stateless: it has no fields and references no fields from other classes. The transient state for a particular computation exists solely in local variables that are stored on the thread's stack and are accessible only to the executing thread. er thread accessing the same Stateless Factorizer; because the two threads do not share state, it is as if they were accessing different instances. Since the actions of a thread accessing a stateless object cannot affect the correctness of operations in other threads, stateless objects are thread-safe.
像大多数servlet的实现的那样,无状态分解就是没有被其他类应用的域和引用,也没有引用其他的类。一次特定的计算中的瞬时状态保存在线程的栈内存中,不会被其他线程访问。访问一个无状态的因子的线程不会影响其他访问该因子的线程,因为两个线程不会分享状态。就如同他们在分别访问两个实例。由于访问一个无状态的对象的线程的动作不会妨碍其他线程的正确性,因此无状态对象是线程安全的。
Stateless objects are always thread-safe.
无状态对象永远是线程安全的。

The fact that most servlets can be implemented with no state greatly reduces the burden of making servlets thread-safe. It is only when servlets want to remember things from one request to another that the thread safety requirement becomes an issue.
大多数servlet可以被设计成线程安全的现实极大的降低了把servlet做成线程安全这种事情的难度。只有一个servlet想要从一个request记住某些事情的时候,线程安全的需求才值得被重视。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值