Java multithreading and java threads
1. threads are created and started in Java. There are two ways to implement multithreading:
Inherit from java. lang. Thread class
Implement the java. lang. Runnable interface
1.1 inherit the Thread class creation Thread inherit the Thread class creation and start the Thread steps:
1. Define the subclass of the Thread and override the run () method of the class. The method body of the run () method indicates the task to be completed by the Thread. Run () is called a thread execution body.
2. Create a sub-class instance of the Thread, that is, create a Thread object.
3. Call the start () method of the thread object to start the thread.
1.2 create a thread using the Runnable interface to create and start a thread using the Runnable interface:
1. Define the implementation class of the Runnable interface and rewrite the run () method of the interface. The method body of the run () method indicates the task to be completed by the thread. Run () is called a thread execution body.
2. Create a Runnable implementation class instance and use this instance as the Thread target to implement the Thread object. This Thread object is the real Thread object.
3. Call the start () method of the thread object to start the thread.
PS: multiple thread objects created using Runnable can share the instance attributes of Runnable implementation classes.
2. There are five states in the thread life cycle.
2.1 new state and ready state when the program uses the new Keyword to create a thread, the thread is in the new State.
When the thread object calls the start () method, the thread is ready. A ready thread does not start to run. It can only be run. It depends on the scheduling of the thread scheduler in JVM when the thread starts to run.
PS: You cannot directly call the run () method of a thread. Otherwise, it becomes a call of a common method, rather than an execution thread.
2.2 The running and blocking threads in the ready State obtain the CPU and start to execute the method body of the run () method. Then the thread is in the running state.
When a thread starts running and its CPU is lost at a certain time point, the thread is in a blocking state.
When the following conditions occur, the thread will enter the blocking status (from the running status to the blocking status ):
1. The thread calls the sleep () method to voluntarily discard the CPU resources occupied
2. The thread calls a blocking IO method.
3. The thread tries to obtain a synchronization monitor, but the synchronization monitor is owned by other threads.
4. The thread is waiting for a notification.
5. The thread suspends the thread by calling the suspend () method. This method can easily cause deadlocks.
In the above situations, you can remove the blocking (from the blocking status to the ready status) when the following situations occur ):
1. the thread that calls the sleep () method has passed the specified time
2. The thread-called blocking IO method has returned
3. The thread gets it and tries to get the synchronization monitor.
4. When the thread is waiting for a notification, other threads send a notification.
5. A suspended thread calls the resume () method.
PS: the thread can call the yield () method from the running status to the ready status.
2.3 The thread in the dead state ends in three ways and is in the dead state after completion:
1. The thread's run () execution is complete, and the thread ends normally.
2. The thread throws an uncaptured Exception or Error.
3. The thread calls the stop () method to end the thread. This method may cause a deadlock.
To test whether a thread is dead, you can call the isAlive () method of the thread object. If the thread is in the ready, running, or blocked state, true is returned. When the thread is in the new state, false is returned when two States are killed.
3. The thread control Java thread provides some convenient tools through which the thread execution can be well controlled.
3.1join Thread provides the join () method that allows one Thread to wait for the completion of another Thread. When the join () method of another thread is called during the execution of a thread, the calling thread is blocked until it is executed by the thread of the join () method.
3.2 A background Thread runs in the background, and its tasks provide services for other threads. Such threads are called Daemon threads and Daemon threads or ELF threads.
Background threads have an important feature: If all foreground threads die, background threads automatically die.
Call the setDaemon (true) method of the thread object to set the specified thread to a background thread.
The Thread class also provides an isDaemon () method to determine whether the specified Thread is a background Thread. If it is a background Thread, true is returned; otherwise, false is returned.
By default, the main thread is the foreground.
Frontend and backend threads have an important feature: the subthreads created by foreground threads are foreground threads by default, and the subthreads created by background threads are background threads by default.
PS: setDaemon (true) sets the thread to the background thread and must be called before the start () method.
3.3 Thread sleep if you need to pause the Thread that is being executed for a period of time and enter the blocking status, you can call the static sleep () method of the Thread class.
The 3.4 Thread concession yield () method is similar to the sleep () method. It is also a static method of the Thread class. It can also suspend the currently executed Thread, but it does not block the thread. It just transfers the thread to the ready state.
When a thread calls the yield () method to suspend a thread, only a ready thread with the same priority as the thread or higher priority will get the chance to execute the thread.
3.5 thread priority each thread has a certain priority. A thread with a higher priority has more opportunities for execution, and a thread with a lower priority has fewer opportunities for execution.
The default priority of the main thread is normal. The default priority of each thread is the same as that of the parent thread created for it.
The Thread class provides the setPriority (int newPriority) method and the getPriority () method to set and obtain the priority of the specified Thread. The parameter value range of the setPriority (int newPriority) method is 1-10, you can also use three static constants of the Thread class.
MAX_PRIORITY: The value is 10.
MIN_PRIORITY: The value is 1.
NORM_PRIORITY: The value is 5.
PS: Java provides 10 thread priorities, but not all operating systems support these 10 priorities. Therefore, we should try to avoid directly setting priorities with numbers, three static constants should be used to set priority, so that the program can be transplanted better.
4. Thread Synchronization 4.1 thread security issues when multiple threads simultaneously access an object, thread security issues may occur.
4.2 synchronization monitor to solve thread security problems, Java's multi-thread support introduces synchronization monitor.
4.2.1 one way to use the synchronization monitor for the synchronization code block is to synchronize the code block.
Synchronized (obj ){
... // The code here is the synchronization code block
}
The obj In the parentheses behind synchronized is the synchronization monitor. The above Code indicates that the synchronization monitor must be locked before the thread starts to execute the synchronization code block.
At any time, only one thread can lock the synchronization monitor.
4.2.2 one way to use the synchronization monitor is the synchronization method.
For the synchronization method, you do not need to explicitly specify the synchronization monitor. The synchronization monitor of the synchronization method is this, that is, the synchronization method itself.
Public synchronized void play (){
... // Synchronization method body
}
The synchronous method can easily implement the thread security class. The thread security class has the following features:
1. Objects of this class can be securely accessed by multiple threads
2. Each thread will get the correct result after calling any method of this object.
3. After each thread calls any method of the object, the object remains in a reasonable state.
4.2.3 release synchronization monitor lock method:
1. The synchronization method and code block of the current thread are executed.
2. The Synchronization Method of the current thread, the break and return in the synchronization code block terminate the method, and the execution of the code block continues.
3. An Error or Exception occurs in the synchronization method and code block of the current thread, causing the method and code block to end abnormally.
4. When the current thread executes the synchronous method and the synchronous code block, the program executes the wait () method of the synchronization monitor object, and the current thread is suspended.
The thread will not release the synchronization monitor in the following situations:
1. When the current Thread executes the synchronous method and the synchronous code block, the program calls the Thread. sleep () and Thread. yield () Methods to pause the execution of the current Thread.
2. When the current thread executes the synchronization code block, other threads call the suspend () method of the thread to suspend the thread. This method can easily cause deadlocks.
4.3 synchronization locks start from Java 5. Java provides a powerful synchronization mechanism that you plan to give you-by displaying and defining synchronization lock objects for synchronization. Under this mechanism, the Lock object is used as the synchronization Lock.
Lock provides a wider range of Lock operations than Synchronization Methods and code blocks. The Lock implementation allows a more flexible structure and can have very different attributes, multiple related Condition objects are supported.
Lock is a top-up multi-thread access tool for shared resources. Generally, a Lock provides exclusive access to shared resources. Only one thread can Lock the Lock object at a time. The Lock object should be obtained before the thread starts to access shared resources.
Some locks may allow concurrent access to shared resources, such as ReadWriteLock ).
Lock and ReadWriteLock are two root interfaces provided by java5. they provide a ReentrantLock implementation class for Lock and a ReentrantReadWriteLock implementation class for ReadWriteLock.
Common ReentrantLock formats are as follows:
Import java. util. concurrent. locks. reentrantLock; public class LockTest {private final ReentrantLock lock = new ReentrantLock (); public void play () {lock. lock (); try {// code to ensure thread security} finally {lock. unlock ();}}}
The ReentrantLock lock is reentrant. That is to say, a thread can lock the ReentrantLock that has been locked again. A lock-protected code can call another method protected by the same lock.
4.4 Deadlock a deadlock occurs when two threads wait for each other to release the synchronization monitor. Therefore, we must take measures to avoid deadlocks during multi-threaded programming.
5. thread communication when a thread runs in the system, the thread scheduling has a certain degree of transparency, the program usually cannot accurately control the thread rotation, but we can use some mechanisms to ensure the coordinated running of the thread.
5.1 traditional thread communication in order to achieve inter-thread communication, the wait (), Y (), and yyall () methods provided by the Object class can be used, however, these three methods must have a synchronous monitor object to call.
1. For synchronous Methods modified using synchronized, because the default instance (this) of this class is the synchronization monitor, you can directly call these three methods in the synchronization object.
2. For Synchronous Code blocks modified using synchronized, the synchronization monitor is an object in the brackets behind synchronized. Therefore, you must use this object to call these three methods.
Meanings of the three methods
1. wait () method: causes the current thread to wait, knowing that other threads call the notify () method or notifyAll () method of the synchronization Monitor
2. Y () method: Wake up a single thread waiting on this synchronization Monitor
3. yyall () method: Wake up all threads waiting on this synchronization Monitor
5.2 use Condition to control thread communication if the program does not use the synchronized keyword to ensure synchronization, but directly uses the Lock Object to ensure synchronization, there is no implicit synchronization monitor in the system, you cannot use the preceding three methods for communication.
When the Lock object is used to ensure synchronization, Java provides a Condition class to ensure coordination. The Condition can be used to release the Lock Object for threads that get the Lock object but cannot continue execution, the Condition object can also wake up other waiting threads.
In this case, Lock replaces the synchronization method or code block, and Condition replaces the synchronization monitor function.
The Condition instance is bound to a Lock object. To obtain the Condition instance of a specific Lock instance, call the newCondition method of the Lock object. Condition provides the following three methods.
1. await () method: similar to the wait () method on the implicit synchronization monitor, this causes the current nickname to wait until other threads call the signal () method of the Condition or signalAll () method () method to wake up this thread
2. signal () method: Wake up a single thread waiting on this Lock Object
3. signalAll () method: Wake up all threads waiting on this Lock Object
5.3 using a blocking Queue to control thread communication Java 5 provides a BlockingQueue interface. Although it is also a sub-interface of Queue, its main role is not as a container, but as a tool for thread synchronization. BlockingQueue has a feature: When the producer thread tries to add an element to BlockingQueue, the thread is blocked if the queue is full. When the consumer thread tries to retrieve an element from BlockingQueue, if the queue is empty, the thread is blocked. The two threads of the program can control thread communication by adding elements to BlockingQueue and extracting elements.
BlockingQueue provides the following two methods to support blocking,
1. put (E) method: Try to put the Eelement into BlockingQueue
2. take () method: Try to retrieve the element from the BlockingQueue Header