Java Multithreading Core technology carding (with source)
- Java Multithreading Core Technology combing the source code
- Write in front
- Java multithreading
- Concurrent access to objects and variables
- Inter-thread communication
- Use of lock
- Timer
- Single-instance mode and multithreading
- Supplements replenishment
- Resources
This paper combs the basics of multithreading, including the basic use of multithreading, the concurrent access of objects and variables, inter-thread communication, lock usage, timers, singleton patterns, and thread states and thread groups.
Write in front
Spent a week reading "Java Multithreaded Programming Core technology" (Gaohong), this book is a summary of the books, almost all the examples, I have personally knocked over, and uploaded to my github, interested friends can go to my github download. The source code uses MAVEN constructs, multithreading this part source code is in the java-multithread
module.
- Warehouse Address: Java-learning
- git clone:
[email protected]:brianway/java-learning.git
Java multithreading
Basic knowledge
- There are two ways to create a thread: 1. Inherit the thread class, 2. Implement the Runnable interface. The connection between the two can refer to my previous post, "Java Foundation Consolidation Notes (5)-Multi-thread traditional multi-threading"
- Some basic api:isalive (), Sleep (), getId (), yield (), etc.
isAlive()
Test whether the thread is active
sleep()
Let "executing thread" hibernate
getId()
Get thread unique identity
yield()
Discard the current CPU resources
- Deprecated APIs:,,
stop()
suspend()
resume()
etc., have been deprecated because of the potential for data to be out of sync.
- Several ways to stop a thread:
- Use the exit ID to cause the thread to exit normally, the Run method completes.
- Use the interrupt method to break the thread
- Priority of threads: inheritance, rule, randomness
- The precedence of a thread is inherited. For example, thread A starts thread B, the same as B and a priority
- The priority of a thread is rule-of-law. CPU tends to prioritize high-resource threads
- The priority of a thread is random. Precedence is not the same as execution order, and the relationship is not deterministic
- Two types of threads in Java: User thread and Daemon (Daemon) thread.
- Daemon thread: The daemon thread is automatically destroyed when a non-daemon thread does not exist in the process. Typical examples are: garbage collection threads.
Comparison and discrimination
- a thread and the current thread: The current thread refers to the thread that is running and can be determined by the
CurrentThread ()
method return value. For example, the Run method is called directly in the Main method, and the start method of the calling thread is printed with a different result than the current thread.
-
interrupted ()
and isinterrupted ()
-
interrupted ()
are static methods of the class, Tests if the front thread is already in the interrupt state and has the ability to clear the status flag to false after execution.
-
isinterrupted ()
is an instance method of a class that tests whether the thread object is already in a break state, but does not know the status flag.
-
sleep ()
and Wait ()
differences:
- Sleep () is the static (static) method of the thread class; Wait ( Method is the method in the object class
- sleep () keeps the lock on the object while sleeping (), while wait () sleeps, releasing the object lock
- after the sleep () sleep time expires, the thread does not necessarily execute immediately, This is because other threads may be running and are not scheduled to abort execution unless the thread has a higher priority, wait () wakes the thread in the current waiting pool with notify or notifyalll or specifies sleep time
- Wait () Must be placed in synchronized block, otherwise the
java.lang.IllegalMonitorStateException
exception will be thrown at runtime
Method |
whether to release the lock |
Notes |
Wait |
Is |
Wait and Notify/notifyall are paired and must be called in the Synchronize block. |
Sleep |
Whether |
Enables low-priority threads to get execution opportunities |
Yield |
Whether |
The yield method gives the current thread the CPU possession, but the time to make it out is not settable |
Concurrent access to objects and variables
synchronized
Key words
- Calling the method declared with the keyword synchronized is queued. But if thread a holds a lock on an object, then thread B's method of asynchronously invoking a non-synchronized type is unrestricted.
- Synchronized lock re-entry: Once a thread obtains an object lock, it can obtain a lock on the object when it is requested again. At the same time, subclasses can invoke the synchronization method of the parent class through the reentrant lock.
- Synchronization does not have inheritance.
- The object monitor used by synchronized is one, which must be the same object
- Synchronized synchronous methods and synchronized synchronous code blocks.
- Blocking for other synchronized synchronous methods or code block calls.
- At the same time only one thread can execute the code in the Synchronized method/code block
- Synchronized (not this object x), the X object as the object monitor
- Synchronizing when multiple threads are executing simultaneous
synchronized(x){}
code blocks
- Synchronous effect when other threads execute Synchronizd synchronization method in X object
- Synchronous effect when other threads execute the synchronized (this) block in the X object method
- Static synchronous synchronized method and synchronized (class) code block: holds the current corresponding class class.
Private stack diagram for threads
- Volatile keyword: The primary role is to make a variable visible across multiple threads ... The volatile keyword is mandatory to take a value from the public stack, not to get the value of the variable from the thread private data stack
- Setting the state bit (without the volatile keyword) in a while loop in a method is not feasible outside the state position bit, and the loop does not stop, such as the JVM in-server mode.
- Cause: The value in the private stack is not synchronized with values in the public stack
- Volatile increases the visibility of instance variables across multiple threads, but does not support atomicity
- Atomic class: An atomic type is a type that is available for an atomic operation and can be thread safe without a lock. But the atomic class is not completely safe, although the atomic operation is secure, but the call between methods is not atomic and needs to be synchronized.
Reading public Memory graphs
Differentiation and piecemeal supplementation
- Synchronized static and non-static methods: The Synchronized keyword and static method are locked for class classes and can work on all instance objects of the class The Synchronized keyword added to the non-static static method is to lock the object and work on the object. These two locks are not the same lock.
- Synchronized and volatile comparison
- 1) keyword volatile is a lightweight implementation of thread synchronization, performance is better than synchronized, and volatile can only modify variables, synchronized can be modified methods and code blocks.
- 2) Multi-threaded access volatile does not block, synchronized will appear blocked
- 3) volatile can guarantee data visibility, not guaranteed atomicity, synchronized can guarantee atomicity, and can indirectly guarantee visibility, because synchronized will synchronize the private memory with the data in public memory .
- 4) volatile solves a variable's visibility across multiple threads, and synchronized solves the synchronization of multiple threads accessing resources.
- string constant pool attribute, so in most cases, the synchronized code block does not apply to string as the lock object.
- Multi-threaded deadlock. Using the JDK's own tool, the JPS Command +jstack command monitors for deadlocks.
- Built-in classes and static built-in classes.
- The change of the lock object.
- When an exception occurs on a thread, the locks it holds are automatically freed.
Diagram of the working process of variables in memory
Inter-thread communication
- wait/notification mechanism:
wait()
and notify()
/ notifyAll()
. Wait causes the thread to stop running and notify to keep the stopped thread running.
wait()
: Waits for the thread that is currently executing the code to place the pre-execute queue.
- Before calling Wait (), the thread must obtain an object-level lock on the object;
- After the wait () method is executed, the current thread immediately releases the lock;
- The thread competes with other threads to regain the lock before returning from Wait ()
- The Interrup () method of the calling thread presents a interrupedexception exception when the thread is in the wait () state
wait(long)
Is whether to wait for a thread to wake the lock at a certain time, or to wake automatically when the timeout occurs.
notify()
: Notifies other threads that may wait for an object lock on the object. Randomly picks a wait-state thread that waits for the object lock to get the object.
- Before calling notify (), the thread must obtain an object-level lock on the object;
- After the Notify () method is executed, the lock is not released immediately, and the current thread will not release the lock until the synchronized code block is exited.
- Notify () only randomly notifies one thread at a time to wake up
notifyAll()
And notify()
almost, just so that all the "all" threads waiting for the same shared resource in the queue are exited from the wait state and into the operational state.
- Each lock object has two queues: a ready queue and a blocking queue.
- Ready queue: Store the thread that will acquire the lock
- Blocking queues: Storing blocked threads
- Producer/Consumer Model
- "Suspended animation": Thread into the waiting waiting state, in the process of suspended animation all threads are waiting state.
- The main cause of suspended animation: it is possible to wake up in succession. Notify Wake up is not necessarily heterogeneous, perhaps the same kind, such as "producer" wakes Up "producer".
- Resolution of suspended Animation: Change Notify () to Notifyall ()
- The wait condition changes, an exception may occur, and if the if is changed to a while
- Inter-thread communication through pipelines: one thread sends data to the output pipeline, and another thread reads data from the input pipeline.
- BYTE stream:
PipedInputStream
andPipedOutputStream
- Character Stream:
PipedReader
andPipedWriter
join()
: Waits for the thread object to be destroyed, with the effect of making the thread queue.
- The join () encounters an exception with the interrupt () method.
join(long)
can set the waiting time
join
synchronized
the difference: Join waits internally using the Wait () method, and synchronized uses the object monitor principle as the synchronization
join(long)
sleep(long)
difference: Join (long) is implemented internally using wait (long), so join (long) has the feature of releasing the lock; Thread.Sleep (long) does not release the lock.
ThreadLocal
Class: Each thread binds its own value
- Override the method of the class to
initialValue()
initialize the variable to resolve the get () return null problem
InheritableThreadLocal
The class can take the value inherited by the parent thread in the child thread.
Use of lock
ReentrantLock
Classes: Implementing synchronous mutexes between threads, more flexible than synchronized
lock()
, the called thread holds the object monitor, and the effect is the same as synchronized
- Use
Condition
implementation wait/notification: More flexible than wait () and notify ()/notyfyall (), for example, to implement multi-channel notifications.
- Call Lock.lock () before calling Condition.await () to get the synchronization monitor
Comparison between object and condition method
Object |
Condition |
Wait () |
Await () |
Wait (long timeout) |
Await (long time,timeunit unit) |
Notify () |
Signal () |
Notifyall () |
Signalall () |
Some API
Method |
Description |
int getHoldCount() |
Query the number of times that the current thread holds this lock, that is, the number of calls to the lock () method |
int getQueueLength() |
Returns the number of thread estimates that are waiting to get this lock |
int getWaitQueueLength(Condition condition) |
Returns the number of thread estimates waiting for the given condition associated with this lock Conditon |
boolean hasQueueThread(Thread thread) |
Queries whether the specified thread is waiting to acquire this lock |
boolean hasQueueThreads() |
Query if thread is waiting to get this lock |
boolean hasWaiters(Condition) |
Query whether a thread is waiting for the condition condition associated with this lock |
boolean isFair() |
Judging is not fair lock |
boolean isHeldByCurrentThread() |
Queries whether the current thread holds this lock |
boolean isLocked() |
Query whether this lock is persisted by any thread |
void lockInterruptibly() |
Gets the lock if the current thread is not interrupted and an exception if it has been interrupted |
boolean tryLock() |
Gets the lock only if the lock is not persisted by another thread at the time of the call |
boolean tryLock(long timeout,TimeUnit unit) |
Gets the lock if it is not persisted by another thread within a given wait time and the current thread is not interrupted |
- Fair lock and non-fair lock
- A fair lock indicates that the order in which threads acquire locks is assigned in the Order of locking, FIFO first-out.
- An unfair lock is a preemption mechanism that acquires a lock and acquires a lock randomly.
ReentrantReadWriteLock
Class
- Read share
- Write-Write Mutex
- Read-Write Mutex
- Write read Mutex
Timer
Common APIs
Method |
Description |
Schedule (timertask task, Date time) |
Perform a task on a specified date |
Scheduleatfixedrate (timertask task, Date Firsttime, long period) |
Performs a task in an infinite loop after a specified period of time, by a specified interval |
Schedule (timertask task, long delay) |
The current time to execute this method is a reference time, and the TimerTask task is executed once after the specified number of milliseconds is deferred on this time basis |
Schedule (timertask task, long delay, long period) |
To execute this method, the current time is a reference time, on the basis of which the specified number of milliseconds is deferred, and a timertask task is executed indefinitely at a certain interval of time |
schedule
and scheduleAtFixedRate
The difference: Schedule does not have the pursuit of execution; Scheduleatfixedrate has the pursuit of execution
Single-instance mode and multithreading
- Load Now/"A Hungry Man mode": the instance has been created before invoking the method. Implemented by the static property new instantiation
- Lazy Load/Lazy mode: the instance is created when the Get () method is called. The most common implementation is to instantiate new in the Get () method
- Cons: In a multithreaded environment, there are problems
- Workaround
- Declares the Synchronized keyword, but runs very inefficiently
- Synchronize code blocks with low efficiency
- Synchronous for some important code (instanced statements), with increased efficiency, but with problems
- Double check lock with DCL
- Implementing singleton mode with enum enum data type
Supplements replenishment
Relationship between method and state
- Status of the thread:
Thread.State
enumeration class, reference official website Apienum thread.state
- Thread groups: Thread groups can be wired or threaded, and threads can also be wired to groups. You can manage threads or thread group objects in bulk.
SimpleDateFormat
Non-thread safe, the solution is:
- Creating instances of multiple SimpleDateFormat classes
- Using the Threadlocal class
- Exception handling for thread groups
setUncaughtExceptionHandler()
Sets the exception handler for the specified thread snaplines
setDefaultUncaughtExceptionHandler()
Set exception handler for all thread objects
Resources
- On the lock in Java
- Usage of the Java synchronized keyword
- Java thread (thread) case study the difference between sleep and wait
Author @brianway More articles: personal website |
CSDN |
Oschina
Java Multithreading Core technology carding (with source)