Java theory and practice: portraying thread safety

xiaoxiao2021-03-06  40

Thread security is not a non-real fake proposition

Level: Intermediate

Brian Goetz (Brian@quiotix.com) Chief Consultant, Quiotix Corp November 2003

In July, our concurrent expert Brian Goetz will

Hashtable and

The Vector class is described as "Conditional Thread Safe". Is there a category not thread security? Is it unsafe thread? Unfortunately, thread security is not a non-real-fake proposition, and it defines unexpected difficulties. However, as Brian is this month

Java Theory and Practice Interpretation is very important to categorize the thread security for classes in Javadoc. Please come with

Discussions Forum Share your experience with author and other readers (you can also click on the top or bottom of this article)

Discuss to access the forum).

In Joshua Bloch, the excellent Effective Java Programming Language Guide (see) The title of Article 52 is "Document Thread Safety", where he urged developers to accurately record the paters the thread security What guarantees. Just like most suggestions in the Bloch book, this is also a very good suggestion that repeatedly mentioned, but few implementations (just like Bloch "Don't write code like my brother" in its programming puzzlers conversation.

How many times you look at a class in Javadoc, and guess "Is this class safe?" Due to lack of clear records, readers may make improper assumptions for thread safety of classes. Perhaps they will define non-threaded security leaves for thread safety (this is really bad!), Or assume that you can synchronize objects before calling an object to get thread security (this may be correct, it may not be The worst case is that only illusory thread security may only be provided. Whether in what circumstances, it is best to express the behavior of the class when the instance of the class in multiple threads is clear in the document.

Look at an example of this problem, the Java.Text.SIMPLEDATEFORMAT class is not a thread, but this is not recorded in Javadoc before 1.4 JDK. How many developers mistakenly created a static instance of SimpleDateFormat and use it in multiple threads, and don't know if their programs can run correctly under large loads? Don't do this for your customers or colleagues!

Write down before forgetting (or leave the company) Be sure to record thread safety during the first time to write, access the security needs and behavior when writing it, thanks to you after a few months (Or others) will be much easier to look back. Never understand the situation that happens in an implementation than when writing it. In addition, recording thread security when writing, you can keep your initial idea for thread security, because the maintainer wants to see this record as part of the description of the class.

If thread security is a binary property of the class, you only need to record the class is thread security or thread is not safe. But very unfortunate, it is not so simple. If the class is not a thread secure, can it become a thread safe when the object is accessed each time the object is accessed? Is there an operational sequence that cannot allow other threads to intervene, but it is not only necessary to synchronize the basic operation, but also to synchronize for composite operations? Is there a status dependency between the methods that contain a set of operations that need to be automatically executed? Developers need to master this information when using a class in concurrent applications.

Defining thread security clearly defines thread security unexpectedly, most definitions look completely self-loop. Quick Search Google, you can find the following is a typical thing about thread security code, but there is no definition of help (or can be described):

... You can call from multiple programming threads, no need to interact between threads. ... You can call multiple threads simultaneously, you don't need to call one side. There is such a definition, it is not surprising that we feel so confused for thread safety. These definitions say that "a class can be safely called by multiple threads" Good, of course, it is the case, but it does not help us distinguish between a thread security class and a thread is not safe. class. What is the meaning of security?

In fact, all thread safety definitions have a loop of some program because it must conform to the specification of the class - this is the function of the class, its side effects, which status is effective and invalidated, the front condition , An informal loose description (subject state constraint given by the specification) is applied to the external visible state, that is, those that can be seen by calling their public methods and access their public fields. Not applied to the internal state represented in its private field).

Thread security classes must be threaded, first of all, you must have correct behavior in a single-threaded environment. If a class is correct (this is another way it meets the specifications), then there is no such thing as an operation sequence (read or written public field and calling public method) for this class. Objects are in an invalid state, or any non-variable, front condition, or post-conditionation of the class.

In addition, a class is to be a thread security. When you are accessed by multiple threads, regardless of the timing arrangement or interleaving of these threads regardless of the runtime environment, it must still have the correct behavior as described above, and the code is called There is no additional synchronization. Its effect is that in all threads, the operation of the thread security object is in a fixed, global consistent order.

The relationship between the correctness and thread safety is very similar to the relationship between the consistency and independence used when describing ACID (atomic, consistency, independence, and persistence) transaction: From the perspective of a specific thread, Object operations performed by different threads are successful (although the order is uncertain) rather than parallel.

The state of the method relies on the following code snippet, it iterates an element in a vector. Although all of the Multi-threaded environment is synchronized, it is still unsafe to use this code in a multi-threaded environment, because if another thread happens to delete an element in an error time, then GET () will throw an ArrayIndexOutofboundSexception.

Vector v = new vector ();

// Contains Race Conditions - May Require External Synchronization

For (INT i = 0; i

DOSMETHING (V.GET (i));

}

The thing that happens here is that a pre-condition requires that INDEX must be non-negative and less than size (). However, in multi-threaded environments, there is no way to know if the Size () value of the last found () is still valid, so I

More specifically, this problem is made by the pre-condition of GET () is the fact that is defined in size (). As long as this must use a pattern of a method as another type of input condition, it is a state dependence, it must ensure that the state of the element during the two methods does not change. In general, the only way to do this is exclusively locked the object before calling the first method, and the latter method will be called. In the example of the iterative vector element above, you need to synchronize the Vector object during iteration.

Thread safety is as shown in the example above, thread security is not a non-real-fake proposition. The vector method is synchronized, and the vector is clearly designed to work in a multi-threaded environment. However, its thread security is limited, that is, there is state dependence between some methods (similarly, if the vector is modified by other threads during iteration, then the Iterator returned by Vector.Iterator () will throw the ConcurrentModificationException ). For thread security levels in the Java class, no classification system can be widely accepted, but it is important to record their thread security behavior when writing classes.

Bloch gives a classification method that describes the five-category thread safety: non-variable, thread security, conditional thread security, thread compatibility, and thread alignment. As long as the thread security features are clearly recorded, you don't have the relationship with this system. This system has its limitations - the boundary between all kinds is not 100%, and some cases have not taken care - but this system is a good start. The core of this classification system is whether the caller can or must be surrounded by an external synchronous manner (or a series of operations). The five categories of thread safety are described below.

The ordinary readers of the non-variable books will not feel unexpected when I am praised. The non-variable object must be a thread safe and never require additional synchronization. Because a non-variable object is constructed, the external visible state will never change, never see it is inconsistent. Most of the basic numerical values ​​in the Java class library, such as Integer, String, and Biginteger are not variable.

Thread security thread security objects have the properties described in the "Thread Safety" section above - the constraints specified by the class are still valid when accessible by multiple threads, regardless of how the runtime environment is arranged, threads No additional synchronization is required. This thread security guarantee is very stringent - many classes, such as HashTable or Vector not meet this strict definition.

Conditional Thread Security We discussed the conditional thread safety in the "concurrency collection class" in July. Conditional thread security classes can be a thread safely, but some operation sequences may require external synchronization. The most common example of conditional thread security is to traverse itself from HashTable or Vector or returned iterator - the Fail-FAST iterator returned by these classes assumes that the underlying collection does not change when the iterator is traversed. To ensure that other threads do not change the collection when traverse, the iterative thread should ensure that it is exclusive access to the integrity of traversal. Typically, exclusive access is guaranteed by the lock-lock-and class documentation should explain which lock (usually the internal monitor of the object).

If you record a conditional thread security class, you should not only record it is secure, but also to record the concurrent access to which of the operation sequences must be prevented. Users can reasonably assume that other operational sequences do not require any additional synchronization.

Thread compatible thread compatibility classes are not threads, but can be safely used in concurrent environments by proper use of synchronization. This may mean to encircle each method with a Synchronized block, or create a wrapper object, where each method is synchronized (just like Collections.SynchronizedList ()). It is also possible to enclose some of the sequences with the Synchronized block. In order to maximize the use of thread compatible classes, if all calls use the same block, then the caller should not be synchronized with the block. This will make thread-compatible objects as variable instances in other objects, so that the synchronization of their owner objects can be utilized.

Many common classes are thread compatible, such as collection class ArrayList and HashMap, Java.Text.SIMPLEDATEFORMAT, or JDBC Class Connection and ResultSet.

Thread alignment peers are classes that cannot be safely rendered in concurrent use regardless of whether or not external synchronization is called. Thread opposing is rare, and the class modifies static data, and static data affects other classes of other classes executed in other threads, and threads are usually occurring. An example of thread opposing class is a class that calls System.setOut (). Other thread safety records Consider thread security classes (and classes with lower thread security) may allow or do not allow caller locking objects for exclusive access. The HashTable class has the internal monitors of all synchronous uses objects, but the ConcurrentHashMap class is not the case, in fact there is no way to lock a ConcurrentHashMap object for exclusive access. In addition to recording thread safety programs, you should also record certain locks - such as object's internal locks - a special meaning of the behavior of classes.

By recording class record as thread security (assuming that it is indeed thread secure), you provide two valuable services: You know the maintenance of the class does not affect the modification or expansion of its thread security, you still The user who knows the class can not use the external synchronization when using it. By recording class records as threads or conditional threads, you will inform users of the user to be safely used in multi-threads by proper use of synchronization. By recording class into threads, you will inform users that even if they use external synchronization, they cannot safely use this class in multithreading. No matter which case, you have prevented them before the potential serious problems, and it is very expensive to find and repair these issues.

Conclusion A class of thread security behavior is the inherent part of its specification, which should be part of its document. Since (also) is not described in the statement of a thread security behavior, a text must be described. Although Bloch's thread safety level has not covered all possible situations, it is a good starting point. If each class adds this thread behavior to its Javadoc, then it is certain that we will benefit.

Reference

Please participate in the discussion of this article in the discussion forum. (You can also access the Forum on the top or bottom discussion at the top of the article.) Read all articles of the Java Theory and Practice Series of Brian Goetz. Especially the following sections related to this column:

"Do I have to prepare those content?" (August 2002), it provides an example of Javadoc. "Change or unchanged?" (February 2003), it discusses the benefits of invariance for thread safety. "Concurrent Collection Class" (July 2003), it analyzes the scalability of the bottleneck and how to achieve higher concurrency and throughput in the shared data structure. The definitions of the thread security are compared in "Understanding JTS, Part 1" (DeveloperWorks, March 2002). Doug Lea's Concurrent Programming in Java, Second Edition (Addison-Wesley, 1999) is a monograph on complex issues related to multi-threaded programming in the Java application. JOSHUA Bloch's Effective Java Programming Language Guide (Addison-Wesley, 2001) One book "Document Thread Safety" describes the five classification described herein. Neel Kumar 's "Write a valid thread security class (developerWorks, April 2000) tells you how to have" efficiency "and" thread security ". You can find hundreds of articles about Java on all aspects of Java on the developerWorks Java technology area.

转载请注明原文地址:https://www.9cbs.com/read-72313.html

New Post(0)