Multi-thread programming learning Summary

Source: Internet
Author: User
Tags time in milliseconds
Document directory
  • Synchronized Method
  • Synchronized Block
  •  
  • Blocking Method Comparison
  •  
  • Wait () and notify () Methods
  •  
  • Join () method
Concepts and Principles of threads

Why is multithreading used?

In order to complete tasks and utilize CPU resources more efficiently, the current operating system is designed as a multi-task operating system, while multiple processes and multithreading are the way to implement multiple tasks.

What are processes and threads?

A process is an application running in the memory. Each process has its own memory space. A process can start multiple threads. A process is the minimum unit for the OS to allocate resources. A thread is an execution process in a process. A process can run multiple threads. A thread always belongs to a process. multiple threads in the process share the memory of the process. A process is the smallest unit of OS scheduling.

How does it work?

  1. Multithreading is a mechanism that allows concurrent execution of Multiple Instruction Streams in a program. Each instruction stream is called a thread and is independent of each other. A thread is also called a lightweight process. It has independent execution control like a process and is scheduled by the operating system. The difference is that the thread does not have independent storage space, instead, it shares a storage space with other threads in the process, which makes the communication between threads much simpler than the process.
  2. Specific to the Java memory model, Because Java is designed as a cross-platform language, a unified model is also required for memory management. The system has a main memory (main memory). All variables in Java are stored in the main memory, and all threads are shared. Each thread has its own working memory (Working Memory)-call stack, which stores copies of some variables in the main memory, the thread operates on all variables in the working memory, and the threads cannot directly access each other. variable transmission must be completed through the main memory.
  3. The execution of multiple threads is concurrent, that is, logically "at the same time", regardless of whether it is physically "at the same time ". If the system only has one CPU, it is impossible to "simultaneously. The biggest difference between multithreading and traditional single-Thread Programming is that the control flow of each thread is independent of each other, so that the code between each thread is executed in disorder, this will cause issues such as thread scheduling and synchronization.

 

Thread status conversion

The state conversion of a thread is the basis of thread control. The thread status can be divided into five states: new, ready, running, waiting/blocking, and dead. Use a diagram to describe it as follows:

1. New State: the thread object has been created and the START () method has not been called on it. 2. ready state: When the thread is qualified to run, but the scheduler has not selected it as the state of the thread when it is running. When the START () method is called, the thread first enters the runable state. It also returns to the ready state after the thread is running or after it is in the blocking, waiting, or sleep status. 3. Running status: the thread scheduler selects a thread from the ready thread pool as the status of the current thread. This is the only way for a thread to enter the running state. 4. Waiting/blocking/sleep status: the thread is not allocated CPU time and cannot be executed. It may be blocked in I/O or synchronization lock. In fact, the three States are combined into one. The common feature is that the thread is still active, but there are currently no conditions to run. In other words, it is runable, but if an event appears, it may return to the runable status. 5. Dead state: When the thread's run () method is completed, it is considered dead. Calling stop () or destroy () has the same effect, but is not recommended, the former produces an exception, while the latter forces termination and does not release the lock. This thread object may be active, but it is no longer a separate thread. Once a thread dies, it cannot be resumed. If the START () method is called on a dead thread, a java. Lang. illegalthreadstateexception is thrown.

 

Lock Mechanism

The essence of the thread lock mechanism is to solve the mutex problem in thread communication. Because we can use private keywords to ensure that data objects can only be accessed by methods, we only need to propose a mechanism for methods. This mechanism is the synchronized keyword, which includes two usage methods: synchronized Method and synchronized block. Note:Each class instance corresponds to a lock, and synchronization and mutex are relative to multithreading..

Synchronized Method

The synchronized method is declared by adding the synchronized keyword to the method declaration. The syntax is as follows:

public synchronized void procData();

Synchronized Method principle: when multiple threads access the same Synchronized Method, the lock of the class instance that calls this method must be obtained before execution. Otherwise, the thread is blocked. Once the method is executed, the lock is exclusive until the lock is released when it is returned from the method. Then, the blocked thread can obtain the lock and re-enter the executable status. This mechanism ensures that, at the same time, only one of all the member functions declared as synchronized is in the executable state (because at most only one member function can obtain the lock corresponding to this type of instance ), this effectively avoids access conflicts between class member variables (as long as all methods that may be used to invoke class member variables are declared as synchronized ).

In Java, not only are class instances, but each class also corresponds to a lock. In this way, we can declare the static member function of the class as synchronized, to control its access to static member variables of the class.

Synchronized: if a large method is declared as synchronized, the efficiency will be greatly affected. Typically, if you declare the thread-class method run () as synchronized, since the thread is always running throughout its life cycle, it will never succeed in calling any Synchronized Method of this class. Of course, we can put the code of the member variable of the category class into a special method, declare it as synchronized, and call it in the main method to solve this problem, but Java provides us with a better solution, that is, the synchronized block.

Synchronized Block

Use the synchronized keyword to declare the synchronized block. The syntax is as follows:

Synchronized (syncobject ){
// Code that allows access control
}

The synchronized block is a code block in which the Code must obtain the lock of the object syncobject (as described earlier, it can be a class instance or class) before execution. The specific mechanism is described earlier. It is highly flexible because it can target any code block and can specify any locked object.


Blocking Mechanism

The essence of the blocking mechanism is to solve the synchronization problem of thread communication. The lock and blocking mechanisms solve the problem of mutual exclusion and synchronization in thread communication.

To solveShared storage ZoneIntroduced the lock mechanism to check the access conflict between multiple threads.Shared resourcesObviously, the lock mechanism is not enough, because the resources required at any time are not necessarily ready for access. In turn, there may be more than one resource ready at the same time. To solve the access control problem in this case, we introduced support for the blocking mechanism.

Blocking means to pause the execution of a thread to wait for a condition (for example, a resource is ready ). Java provides a large number of methods to support blocking. Let's analyze them one by one.

  1. Sleep () method: Sleep () allows you to specify a period of time in milliseconds as a parameter, which causes the thread to enter the blocking state within the specified time, And the CPU time cannot be obtained. The specified time is too long, the thread enters the executable status again. Typically, sleep () is used to wait for a certain resource to be ready: after the test finds that the condition is not met, the thread is blocked for a period of time and then re-tested until the condition is met.
  2. Suspend () and resume () Methods: Two methods are used together. Suspend () causes the thread to enter the blocking state and will not be automatically restored. The corresponding resume () must be called to re-enter the executable state of the thread. Typically, suspend () and resume () are used to wait for the results produced by another thread: after the test finds that the results have not yet been produced, the thread is blocked. After the results are produced by another thread, call resume () to restore it.
  1. Yield () method: Yield () causes the thread to discard the current CPU time, but does not block the thread, that is, the thread is still executable and the CPU time may be allocated again at any time. The effect of calling yield () is equivalent to that the scheduler considers that the thread has executed enough time to go to another thread.
  2. Wait () and notify () Methods: Two methods are used together. Wait () enables the thread to enter the blocking state. It has two forms: One allows specifying a period of time in milliseconds as a parameter, the other has no parameters. When the corresponding notify () is called or the thread enters the executable state after the specified time is exceeded, the latter must call the corresponding notify.
Blocking Method Comparison
  1. The core difference between 2 and 4 is that all the methods described above will not release the occupied lock (If it is occupied), While this method is the opposite. The above core differences lead to a series of detailed differences.
  2. First, all the methods described above belong to the Thread class, but this pair is directly affiliated to the object class, that is, all objects have this pair of methods. This pair of methods will release the occupied lock when blocking, and the lock is available to any object. Calling the wait () method of any object will cause thread blocking, and the lock on the object is released. However, calling the notify () method of any object causes the wait () method of the object to be called () method ).
  3. Secondly, all the methods described above can be called anywhere, but this pair of methods must be called in the synchronized method or block for a very simple reason, the lock can be released only when the current thread occupies the lock in the synchronized method or block. In the same way, the lock on the object that calls this method must be owned by the current thread so that the lock can be released. Therefore, this pair of method calls must be placed in such a synchronized method or block. The lock object of this method or block is the object that calls this pair of methods. If this condition is not met, the program can still be compiled, but the illegalmonitorstateexception will occur at runtime.

 

The preceding features of the wait () and notify () methods determine that they are often used together with the synchronized method or block, by comparing them with the inter-process communication machine of the operating system, we will find their similarity: the synchronized method or block provides functions similar to the operating system primitive, their combination is used to solve various complex inter-thread communication problems.

Wait () and notify () Methods
  1. The thread that calls the notify () method to remove blocking is randomly selected from the thread that is blocked by calling the wait () method of the object, we cannot predict which thread will be selected, so we should be very careful when programming to avoid problems caused by such uncertainty.
  2. In addition to notify (), there is also a method notifyall () that can also play a similar role. The only difference is that calling the notifyall () method will call the wait () and all the blocked threads are all blocked at one time. Of course, only the thread that gets the lock can enter the executable state.

When talking about blocking, we can't help but talk about deadlocks. A brief analysis shows that calls of the suspend () method and the wait () method without specifying the timeout period may lead to deadlocks. Unfortunately, Java does not support avoiding deadlocks at the language level. We must be careful in programming to avoid deadlocks.

We have analyzed various methods for implementing thread blocking in Java. We have focused on the wait () and notify () methods, because they have the most powerful functions, they are also the most flexible to use, but this also leads to low efficiency and error-prone. In actual use, we should use various methods flexibly to better achieve our goal.

Join () method

The join () method can be used to block the current thread to wait for the termination of a specific thread (the thread that calls the join. The thread object cannot call the join of its own thread in its executable body.


Thread priority

The thread priority indicates the importance of the thread. When multiple threads are in the executable status and wait for the CPU time to be obtained, the thread scheduling system determines to whom to allocate the CPU time based on the priority of each thread. A thread with a higher priority has a larger chance to obtain the CPU time. A thread with a lower priority is not without a chance, it's just a little opportunity.

You can call the methods of the thread class getpriority () and setpriority () to access the priority of the thread. The priority of the thread is between 1 (min_priority) and 10 (max_priority, the default value is 5 (norm_priority ).


Daemon thread and user thread

A thread can be divided into user and daemon: a daemon is a special thread. The difference between a daemon thread and a common thread is that it is not the core of an application, when all the non-daemon threads of an application terminate, the application will terminate even if there are still daemon threads running. Otherwise, as long as there is a non-daemon thread running, the application will not be terminated. Daemon threads are generally used to provide services for other threads in the background. You can call the isdaemon () method to determine whether a thread is a daemon thread, or call the setdaemon () method to set a thread as a daemon thread.

My personal understanding of the daemon thread is:Both the user and daemon threads have executable sequences and their own working stacks. The difference is that the daemon thread ends with its parent thread and does not belong to the program itself. Another layer means that the end of the parent thread depends on all its sub-user threads, and is not related to the daemon thread. The difference between them determines that they are used in different scenarios. The daemon thread generally provides services for other threads, such as the garbage collector.

Note that the setdaemon () method must be called before the thread object does not call the START () method. Otherwise, it will not work..


Thread group mechanism
  1. A thread group is a concept unique to Java. in Java, a thread group is a threadgroup-like object, and each thread belongs to a unique thread group, this thread group cannot be changed during the entire life cycle specified during the creation of the thread group. You can call the Thread class constructor that contains threadgroup parameters to specify the thread group. If this parameter is not specified, the thread is affiliated to the system thread group named system by default.
  2. In Java, all thread groups except the pre-created system thread groups must be explicitly created. In Java, each thread group except the system thread group belongs to another thread group. You can specify the thread group to which it belongs when creating the thread group. If not, by default, it is affiliated to the system thread group. In this way, all threads are grouped into a tree with the system thread group as the root.
  3. Java allows us to operate on all threads in a thread group at the same time. For example, we can set the priority of all threads by calling the corresponding methods of the thread group, it can also start or block all threads.
  4. Another important role of Java's thread group mechanism is thread security. The thread group mechanism allows us to distinguish threads with different security features by grouping and process different threads in different groups, the layer structure of the thread group can also be used to support unequal security measures. The threadgroup class of Java provides a lot of methods to facilitate operations on every thread group in the thread group tree and every thread in the thread group.

 

Threadlocal

Java. Lang. threadlocal is local variable (thread local variable ). ItProvide a copy of the variable value for every thread that uses the variable.So that each thread can change its own copy independently without conflict with the copies of other threads. From the thread perspective, it seems that every thread has the variable completely.Threadlocal is essentially a thread-safe hashmap. The key is threadname and the value is the variable in the thread.

  • Synchronized is used for data sharing between threads, while threadlocal is used for data isolation between threads..
  • Threadlocal is used to solve data inconsistency caused by concurrency in multiple threads. ThreadlocalProvides a copy of the data objects concurrently accessed by each thread.By accessing the copy to run the business, the result is that the memory is consumed, but the performance consumption caused by thread synchronization is greatly reduced, and the complexity of thread concurrency control is also reduced.
  • Threadlocal cannot use the atomic type, but can only use the object type. Threadlocal is much easier to use than synchronized.
  • Both threadlocal and synchonized are used to solve multi-thread concurrent access. However, threadlocal is essentially different from synchronized. Synchronized uses the lock mechanism to allow a variable or code block to be accessed by only one thread at a time. Threadlocal provides a copy of the variable for each thread, so that each thread does not access the same object at a certain time, thus isolating multiple threads from sharing data. Synchronized, on the contrary, is used to obtain data sharing when multiple threads communicate.
  • Of course, threadlocal cannot replace synchronized. They process different problem domains. Synchronized is used to implement the lock mechanism, which is more complex than threadlocal.

 

Summary
  • We have learned all aspects of Java multi-threaded programming, including creating threads and scheduling and managing multiple threads. We were deeply aware of the complexity of multi-threaded programming and the inefficiency of multi-threaded programs brought about by thread switching overhead. This also prompted us to seriously consider the question: do we need multithreading? When do I need multithreading?
  • The core of multithreading lies in the concurrent execution of multiple code blocks. The essential feature is that the Code between different code blocks is executed in disorder.Whether or not our program requires multithreading depends on whether it is also its internal characteristic.
  • If our program does not require concurrent execution of multiple code blocks, we naturally do not need to use multithreading. If our program requires concurrent execution of multiple code blocks, we do not need to execute them in disorder, we can use a loop to implement it in a simple and efficient way without using multithreading. Only when it fully complies with the characteristics of multithreading, the strong support of the multithreading mechanism for inter-thread communication and thread management can be used. It is worthwhile to use multithreading.

 

Reference: http://programming.iteye.com/blog/158568 http://lavasoft.blog.51cto.com/62575/51926

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.