Java concurrent programming practice-Chapter 1-thread security, Chapter 2 of java
Java concurrent programming practice-Chapter 1-thread security
2. Thread Security
2.1 What is thread security
Thread security class: When a class is accessed by multiple threads, no matter how scheduled they are in the running environment, how these threads are executed alternately, and the amount of synchronization or collaboration is not required in the called code. This class is thread security class
Thread-safe classes encapsulate any needed synchronization so that clients need not provide their own.
2.1.1. Example: A Stateless Servlet
Stateless objects are always thread-safe.
2.2 atomicity
In a stateful servlet, the state variable count should be an atomic operation under the multi-thread condition, ++ count.
The possibility of incorrect results in the presence of unluky timing is so important in concurrent programming that it has a name: a race condition.
2.2.1 competitive conditions
How to generate: When a correct result depends on the time sequence of the alternate execution of multiple threads, a race condition will occur.
Essence: make judgments or execute a computing based on a potentially invalid observation result.
Most common type: check-then-act (Starbucks AB will meet with friends)
2.2.2 example: Race Condition for delayed Initialization
LazyInitRace if an application is in the application's registry, registration information may be lost, or the views of the same group of registered objects may be inconsistent.
@ NotThreadSafe
Public class LazyInitRace {
Private ExpensiveObject instance = null;
Public ExpensiveObject getInstance (){
If (instance = null)
Instance = new ExpensiveObject ();
Return instance;
}
}
UnsafeSequence if the application is in persistent data, different objects will have the same id, in violation of the integrity constraints of the Identity
@ NotThreadSafe
Public class UnsafeSequence {
Private int value;
/** Returns a unique value .*/
Public int getNext (){
Return value ++;
}
}
2.2.3 compound operations
Such "Read-Modify-write" operations are collectively referred to as compound operations, and compound operations should be atomic.
1. Through the locking mechanism of 2.3
2. Use the existing thread security class AtomicLong
Listing 2.4. Servlet that Counts Requests Using AtomicLong.
@ ThreadSafe
Public class CountingFactorizer implements Servlet {
Private final AtomicLong count = new AtomicLong (0 );
Public long getCount () {return count. get ();}
Public void service (ServletRequest req, ServletResponse resp ){
BigInteger I = extractFromRequest (req );
BigInteger [] factors = factor (I );
Count. incrementAndGet ();
EncodeIntoResponse (resp, factors );
}
}
Where practical, use existing thread-safe objects, like AtomicLong, to manage your class's state. it is simpler to reason about the possible states and state transitions for existing thread-safe objects than it is for arbitrary state variables, and this makes it easier to maintain and verify thread safety.
In practice, try to use the existing thread security class to manage the status
2.3 Lock Mechanism
Example: UnsafeCachingFactorizer
To preserve state consistency, update related state variables in a single atomic operation
To maintain state consistency, you must update all related state variables in an atomic operation.
2.3.1 built-in locks
Java provides a built-in lock mechanism to support atomicity: the synchronized block
These built-in locks are called intrinsic locks or monitor locks
2.3.2 re-import
A thread can obtain an existing lock.
2.4 use locks to protect the status
The same lock must be used to protect all mutable states.
If all methods are synchronized, it will cause active and performance problems.
2.5 activity and Performance
Network or console I/O. Do not hold the lock
3. Object sharing