Six: Blocking of threads
In order to resolve access conflicts on the shared storage area, Java introduced synchronization mechanism. Now let's examine access to multiple threads on shared resources, clearly the synchronization mechanism is not enough, because the resources required at any time are not necessarily ready The resource that is accessed, in turn, the resource prepared at the same time may also be more than one. In order to solve access control problems in this case, Java introduced support for blocking mechanisms.
The blocking refers to the suspension of a thread to wait for a condition (such as a resource ready), and learn the system-made classmates must be very familiar with it. Java provides a large number of ways to support blocking, and let us analyze one by one.
1. Sleep () method: SLEEP () allows you to specify a period of time as a parameter in milliseconds, which enters the blocking state in the specified time, cannot get the CPU time, the specified time is over, the thread is re-entered status.
Typically, Sleep () is used in situations waiting for a certain resource: After the test discovery conditions are not met, the thread blocks the thread to retest and retest until the condition satisfies.
2. Suspend () and resume () Method: Two methods are used, suspend () enables the thread to enter the blocking state, and does not automatically recover, must be called to be called to re-enter the executable state . Typically, Suspend () and resume () are used in situations that are waiting for another thread to generate results: After the test results have not yet occurred, the thread is blocked, and the other thread has a result, calling resume () to restore it. .
3. Yield () method: yield () makes the thread to discard the currently outstanding CPU time, but does not cause threads to block, that is, the thread is still in executable, and may separate the CPU time again. The effect of calling Yield () is equivalent to the scheduler thinks that the thread has executed enough time to go to another thread.
4. Wait () and notify (): Two methods are used, Wait () makes the thread into the blocking state, there are two forms, one for a period of time to specify in milliseconds as a parameter, the other Parameters, the former When the corresponding Notify () is called or beyond the specified time, the thread re-enters the executable, the latter must be called.
It seems that they have no differences between them with suspend () and resume () methods, but in fact they are very different. The core is that all methods of the previously described, and it does not release the lock (if occupied) is blocked, and this pair method is reversed.
The core difference of the above results in a series of details.
First, all the methods described above are affiliated to the Thread class, but this pair is directly affiliated to the Object class, that is, all objects have this pair. It is very incredible, but it is actually very natural, because this pair method is blocked when the lock is blocked, and the lock is any object, and the Wait () method of calling any object causes the thread to block. And the lock on the object is released. The NOTIFY () method calling any object is caused by a random selection in the thread that is incorporated by the WAIT () method of the object (but to wait until the lock is really executable).
Second, all the methods described above can be called anywhere, but this pair of methods must be called in the synchronized method or block, the reason is also very simple, only in the synchronized method or the current thread holds the lock, only lock Can be released. The same truth, the lock on the object called this pair must be owned for the current thread, so that the lock can be released. Therefore, this pair method call must be placed in such a SYNCHRONIZED method or block, the method or block of the block is called the object of this pair of methods. If this condition is not met, the program can still be compiled, but IllegalMonitorStateException exception occurs at runtime. The above features of the WAIT () and Notify () methods determine that they are often used together with the Synchronized method or block, and the communication mechanism between them and * as a system will find their similarities: SYNCHRONIZED method or block provides Similar to * as a systematic primitive, their execution is not interfered by multi-thread mechanism, and this pair method is equivalent to block and wakeup primitives (this pair method is declared as synchronized). Their combination allows us to implement * algorithms such as a series of exquisite processes in the system (such as a signal algorithm), and is used to address various complex thread communication issues.
About Wait () and Notify () methods will then explain two points:
First: Call the notify () method causes the thread that is blocked by the clogging from the thread that is blocked by the Wait () method called the object, we cannot expect which thread will be selected, so it is especially careful when programming. Avoid problems due to this uncertainty.
Second: In addition to NOTIFY (), there is also a method notifyAll () can also play a similar role, the only difference is that all threads that call the notifyAll () method will block all threads that block the Wait () method of the object. All release block. Of course, only the thread that gets the lock can enter the executable state.
When you talk about the blocking, you can't talk about a deadlock. You can find that the SUSPEND () method and the call of the wait () method and the WAIT () method that do not specify the timeout period may result in a deadlock. Unfortunately, Java does not support the avoidance of deadlocks at the language level, we must carefully avoid dead locks in programming.
We have analyzed the various methods of achieving thread blocking in Java. We focus on the WAIT () and Notify () methods because their features are most powerful, but this also leads them. The efficiency is low, it is more likely to be wrong. In actual use, we should use various methods in order to better meet our goals.
Seven: Dazhi Thread
The guarding thread is a special thread. Its and normal threads are not the core part of the application. When all the non-daemon threads of an application are terminated, even if there is still a guarding thread running, the application will also Termination, it is, as long as there is a non-standard thread to run, the application will not terminate. The daemon is generally used to provide services for other threads in the background.
You can determine whether a thread is a daemon by calling method isDaemon (), or you can call method setDaemon () to set a thread as a daemon.
Eight: thread group
The thread group is a Java unique concept. In Java, the thread group is an object of THReadgroup, each thread is affiliated with a unique thread group, which is specified in the thread and cannot be used during the thread. change. You can specify the thread group of the thread belonging by calling the Thread class constructor containing the ThreadGroup type parameters. If there is no specified, thread defaults to system thread group named System. In Java, all thread groups must be explicitly created in addition to the pre-built system thread group.
In Java, each thread group except the system thread group is also part of another thread group, you can specify the thread group members belonging when you create a thread group. If you do not specify, it is default to the system thread group. . In this way, all thread groups form a tree with a system thread group.
Java allows us to perform all threads in a thread group *, such as we can set all the threads in all threads, or block all threads can be started or blocked by calling the corresponding methods of the thread group.
Another important role of Java's thread group mechanism is thread security. The thread group mechanism allows us to distinguish between threads with different security features, different processing of threads of different groups, and can also support the use of unsuitable safety measures through the hierarchy of thread groups. Java's ThreadGroup class provides a large number of ways to facilitate our * work for each of the thread groups in the thread group and each thread in the thread group.
Nine: Summary
In this lecture, we have learned all aspects of Java multi-threaded programming, including creating threads, and scheduling, managing multiple threads. We have a deep understanding of the complexity of multi-thread programming, as well as the inefficiency of multi-threaded programs brought by thread switching, which also prompted us to seriously think about a problem: Do we need multi-thread? When will I need multi-thread?
The core of the multi-thread is that the multiple code blocks are implemented, and the essential features are the code between the blocks. Does our program need multi-thread, it is to see if this is also its intrinsic feature.
If our programs do not require multiple code blocks and implement, it will naturally do not need to use multithreaded; if our program requires multiple code blocks to implement, but we don't ask for trouble, we can use a loop. Simple and efficiently, it is not necessary to use multithreading; only when it is fully compliant with multi-threaded features, multi-threading mechanisms have strong support for communication and thread management in line-building, which is worthwhile. .