2. Thread security 2.1 What is thread-safe
When multiple threads are accessed, the program can be " correct ", which is thread-safe.
An object that has no status (a class that can be understood as having no fields) must be thread safe.
2.2 atomicity
In a typical case, the i++ in a multithreaded state is not secure. Because i++ is actually implemented in a number of steps, the execution of multiple threads can be confusing to each other.
Race condition (Race Conditions)
Threads and threads need to depend on the order of execution to ensure the correctness of the execution results. Then there will be a race condition. For example, set a value in a thread, and then pass another signal variable notification to another thread to read. This kind of coordination is very wrong.
For reordering, refer here: http://ifeve.com/java-memory-model-2/
The most common example: "Check first and then execute"
In a non-synchronous multithreaded environment, what you see is not necessarily true, because the next second may not be the case!
The book cited an example:
You had an appointment with a friend at a Starbucks somewhere, but then you found two Starbucks, A and B, and you didn't find a friend in Starbucks a, so your friend might:
1, at Starbucks B home
2, on the way to Starbucks A and B
If you leave Starbucks a and find somewhere else, then: The next second you leave Starbucks A, the information on your "friends not at Starbucks a" is likely to expire! , because the next second you go out from the front door, your friend may come in through the back door .
2.3 Plus lock mechanism
The Synchronize keyword represents a built-in lock that automatically creates a lock object based on the current usage location, so you don't have to explicitly indicate what lock to use when using it.
Synchronize in the normal member method means that the lock object is represented with this
The Synchronize in the static method means that class is used as the lock object.
Reference: https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.3.6
Re-entry
The recursion of the synchronous method and the subclass call to the parent class method are reentrant. No deadlock occurs.
Re-entry Implementation mechanism:
There's this information in the lock information.
{thread01,1}
Indicates that THREAD01 acquired the lock 1 times. When THREAD01 needs to acquire the lock again, the record is as follows:
{thread01,2}
After the method has finished executing, the number of locks is reduced and the lock is released when the quantity is 0.
3. Sharing 3.1 Visibility of objects
How do I make thread A's row results visible to thread B? Locking
A lock is used to ensure that a write, another read is executed in the desired order, and the result of the write is read. The order of code execution alone is not possible!
Volatile variable
Java provides a synchronization mechanism that is used to guarantee volatile modified variables that can be seen by other threads after being modified in one thread.
The internal mechanism is that the volatile variable is not re-queued or cached to the register.
Precautions:
1.volatile only guarantees visibility, but does not guarantee atomicity, so do not apply to multi-threaded "write" scenarios
2. Multiple volatile in fact separate, does not constitute the overall synchronization
Use volatile with special care, generally used for simple signal transmission, slightly more complex or with a lock bar:
Public classVolatileTest2 { Public Static voidMain (string[] args) {VolatileTest2 test=NewVolatileTest2 (); Test.start (); Try{Thread.Sleep (5000); } Catch(interruptedexception e) {e.printstacktrace (); } test.stop (); } volatile BooleanStop =false; Public voidstart () {NewThread (NewRunnable () {@Override Public voidrun () { while(!stop) {System.out.println ("Running ..."); Try{Thread.Sleep (1000); } Catch(interruptedexception e) {e.printstacktrace (); }}}). Start (); } Public voidStop () {Stop=true; } }
3.2 Release and Escape (Escape)
You need to figure out whether the publicly available data really needs to be made public, because once exposed, the external can be accessed, then you have to consider the problem of multithreading.
In other cases, you might accidentally expose the data externally, such as creating an anonymous inner class in a constructor, or starting a thread. The reason for this is that the constructor function exposes this to an internal class or thread. The "This" itself may not be ready!
(Workaround: Use engineering methods; Define threads first, add another method to start this thread)
3.3 Thread closure
When a thread does not need to share data, it is a good way to ensure thread safety by enclosing the data in threads. The program should avoid data escaping into other threads.
For example, you can use local variables or threadlocal to store thread data.
Ad-hoc Thread Closure
This means that it is entirely up to the program to implement the blocking of data between threads.
Stack closure
Local variables that can be understood as basic types are encapsulated in the execution stack and do not break the stack's closeness.
ThreadLocal
It is a good tool class to implement thread closure. You can think of threadlocal<t> as a map<thread,object>, but the bottom-level implementation is not. The threadlocal data is actually stored in the associated thread object. At the end of the thread, the data is recycled.
Note: Not all global parameters need to be stored in threadlocal, and some people even put the function call parameters here, which will cause the program to be less readable, increase the degree of program coupling and inconvenience maintenance.
3.4 invariance
Immutable data must be thread-safe, so when it comes to avoiding problems with data states, you can try to make it immutable (if it does not change).
Using Final+volatile for thread safety
The final feature
Java Concurrent Programming Practice reading notes (1) thread safety and object sharing