Reprint Source: Http://blog.csdn.net/evankaka, Lin Bingwen Evankaka Original works
Written in the previous words: This article can only say that Java multithreading is a primer, in fact, the Java thread can write a book, but if the most basic you learn to master well, how can more than a step. If you think this article is very simple, it is recommended that you look at the Java and contract the thread pool (Java concurrency Programming and Technical Insider: thread pool in-depth understanding), or see this column: Java Concurrency Programming and Technical insider. You will have a deeper understanding of the threads in the high concurrency scene in Java.
This article mainly discusses the use of multithreading in Java, thread synchronization, thread data transmission, thread state and some of the corresponding thread function usage, overview and so on. Before that, let's take a look at the differences between processes and threads in the operating system:
process: Each process has its own code and data space (process context), and transitions between processes have a higher cost, and a process contains 1–n threads. (Process is the smallest unit of resource allocation)
Threads: The same class of threads share code and data space, each thread has a separate run stack and program counter (PC), and the thread switching overhead is small. (Thread is the smallest unit of CPU scheduling)
Threads and processes are divided into five phases: Create, ready, run, block, terminate.
Multi-process is the operating system can run multiple tasks (programs) at the same time.
Multithreading refers to the execution of multiple sequential streams in the same program.
In Java in order to implement multithreading, there are two ways, one is to continue the thread class, the other is to implement the Runable interface. ( in fact, there should be three, there is also a kind of implementation of the callable interface , and with Future, thread pool use, this article does not say this here, is interested to see here Java Concurrent programming and Technical Insider: callable, Future, Futuretask, Completionservice)
first, extend the Java.lang.Thread class
The method of inheriting the thread class here is a more commonly used one, if you just think of a thread. There are no other special requirements, so you can use thread. ( I recommend using runable, and then explain why ). Let's look at a simple example
package com.zhihua.Thread; /** * Inherit thread class, simple to start a new thread * < Replace function description > <br> * < Please replace with detailed description > * @author Caizh * @since [1.0.0] * @vers
Ion [1.0.0,2017 Year April 13] */public class Demo01 extends thread{private String name;
Public Demo01 (String name) {this.name = name;
public void Run () {for (int i=0;i<5;i++) {System.out.println (name+ "Run" +i);
The try{//Thread.Sleep () method invocation is intended to keep the current thread from hogging the CPU resources acquired by the process alone to allow time for other threads to execute.
Sleep ((int) math.random () *10);
}catch (interruptedexception e) {e.printstacktrace ();
}} public static void Main (string[] args) {Demo01 mTh1 = new Demo01 ("A");
Demo01 mTh2 = new Demo01 ("B"); Mth1.start (); Open thread Mth2.start (); The Start method repeats the call, and the java.lang.IllegalThreadStateException exception//The result of each execution is random}
Output results (each output is different):
B Run 0
A run 0
B Run 1
B Run 2
B Run 3
B Run 4
A Run 1
A Run 2
A Run 3
A run 4
Description: When the program starts running main, the Java Virtual machine initiates a process, and the main thread main and main () call are created. With the method of calling the start of the Demo01 two objects, the other two threads are also started, so that the entire application runs in multiple threads.
Note: the start () method is called not to execute multithreaded code immediately, but rather to make the thread operational (Runnable) and when it is run by the operating system.
From the results of the program running, we can find that multithreaded programs are executed in random order. Therefore, only disorderly execution of the code is necessary to design for multithreading.
The Thread.Sleep () method invocation is intended to allow the current thread to occupy the CPU resources acquired by the process alone, to allow time for other threads to execute.
Virtually all thread code execution orders are indeterminate, and the results of each execution are random. However, the Start method repeats the invocation, and a Java.lang.IllegalThreadStateException exception appears.
Thread1 mth1=new Demo01 ("A");
Thread1 mth2=mth1;
Mth1.start ();
Output:
Exception in thread ' main ' java.lang.IllegalThreadStateException at
java.lang.Thread.start (Unknown Source)
At Com.multithread.learning.Main.main (main.java:31)
a running : 0 A running: 1
a running : 2
A run : 3
a run : 4
second, realize java.lang.Runnable interface
Using Runnable is also a very common one, and we just need to rewrite the Run method. Here's a look at an example.
package com.zhihua.Runnable; /** * Using the Runnable interface to achieve multithreading (more commonly) * Implementation of the Run method can be * < replace the function description > <br> * < Please replace the detailed description > * @author Caizh * @since
[1.0.0] * @version [1.0.0,2017 year April 13] */public class DEMO01 implements runnable{private String name;
Public Demo01 (String name) {this.name = name; @Override public void Run () {i=0;i<5;i++) {System.out.println, name + run:
+ i);
try {thread.sleep (int) math.random () * 10);
catch (Interruptedexception e) {e.printstacktrace (); }} public static void Main (string[] args) {/** * When starting multithreading, you need to first thread through the thread class's construction method
(Runnable Target) * Constructs an object and then invokes the thread object's start () method to run multithreaded code.
*/New Thread (New Demo01 ("C")). Start ();
New Thread (New Demo01 ("D")). Start (); }
}
Output:
C Run: 0
D Run: 0
C Run: 1
D Run: 1
C Run: 2
D Run: 2
C Run: 3
D Run: 3
C Run: 4
D Run: 4
Description
This class has the characteristics of multithreading by implementing the Runnable interface. The run () method is a convention for multithreaded threads. All multithreaded code is inside the Run method. The thread class is actually a class that implements the Runnable interface.
When you start multithreading, you need to first construct the object through the thread class's construction method thread (Runnable target), and then call the Thread object's start () method to run multithreaded code.
Virtually all multithreaded code runs by running the thread's start () method. Therefore, whether to extend the thread class or implement the Runnable interface to implement multithreading, the thread is ultimately controlled by the API of the thread's object. The APIs that are familiar with the thread class are the basis for multithreaded programming. iii. the difference between thread and runnable
If a class inherits thread, it is not appropriate for resource sharing. However, if the Runable interface is implemented, it is easy to achieve resource sharing.
Summarize:
the advantages of implementing the Runnable interface than inheriting the thread class are:
1): Suitable for multiple threads of the same program code to handle the same resource
2): You can avoid the limitations of single inheritance in Java
3): Increase the robustness of the program, code can be shared by multiple threads, code and data independent
4): Thread pool can only be put into implementation runable or callable class thread, can not directly put into the class of inheritance thread
To remind you: The Main method is actually a thread. In Java, so the thread is started at the same time, as to when, which is the first execution, completely see who first get the CPU resources.
in java , you start at least 2 threads per program run . One is the main thread and one is the garbage collection thread. Because every time a class is executed using a Java command, a JVM is actually started, and each JVM actually initiates a process in the operating system. Four, thread state conversion The following diagram is very important. If you can understand this diagram, the understanding of multithreading will be more profound.
1. New State (new): A newly created thread object. 2, Ready State (Runnable): After the thread object was created, other threads called the object's start () method. The thread of this state is in the running thread pool, becomes operational, and waits for access to the CPU. 3, running State (Running): The ready state of the thread to get the CPU, execute program code. 4, blocking state (Blocked): Blocking state is the thread for some reason to give up the use of CPU, temporarily stop running. Until the thread enters the ready state, there is an opportunity to go to the running state. The blocking situation is divided into three types: (i), wait for blocking: The running thread executes the wait () method, and the JVM puts the thread into the waiting pool. (wait will release the held lock) (ii), synchronous blocking: When a running thread acquires a synchronized lock on an object, the JVM puts the thread into the lock pool if the synchronization lock is occupied by another thread. (iii), other blocking: The running thread executes the sleep () or join () method, or when an I/O request is made, the JVM puts the thread into a blocking state. When the sleep () state times out, join () waits for the thread to terminate or timeout, or the I/O process completes, the thread is back in ready state. (Note that sleep does not release held locks) 5, Dead State (Dead): The thread has finished executing or exited the run () method because of an exception, which ends the lifecycle.
Five, thread scheduling
Thread scheduling 1, Tuning thread Priority: Java threads have priority, high priority threads will get more opportunities to run. The precedence of a Java thread is expressed as an integer, and the value range is the 1~10,thread class has the following three static constants:
The static int max_priority
thread can have the highest precedence, with a value of 10. The
static int min_priority The
minimum priority that a thread can have, with a value of 1. The
static int norm_priority The
default priority assigned to the thread, with a value of 5.
The SetPriority () and GetPriority () methods of the thread class are used to set and get the priority of the thread, respectively. Each thread has a default priority. The primary thread's default priority is thread.norm_priority. The priority of a thread has an inheritance relationship, such as the B thread created in a thread, then B will have the same priority as a. The JVM provides 10 thread priorities, but does not map well with common operating systems. If you want the program to be ported to each operating system, you should use only the thread class with the following three static constants as a priority, ensuring that the same priority is used for the same scheduling. 2, Thread sleep: thread.sleep (Long Millis) method, which causes the thread to go to the blocking state. The Millis parameter sets the time of sleep, in milliseconds. When sleep is over, it becomes ready (Runnable) state. The sleep () platform is well ported. 3, Thread-waiting: The Wait () method in the object class causes the current thread to wait until the other thread calls the object's notify () method or Notifyall () Wakeup method. This two wake-up method is also a method in the object class, which behaves equivalent to calling wait (0). 4, Thread compromise: the Thread.yield () method pauses the currently executing thread object, giving the execution opportunity to the same or higher priority thread. 5, thread join: Join () method, wait for other thread to terminate. Calls the join () method of another thread in the current thread, the current thread goes into a blocking state until the other process is finished, and the current thread is again blocked to the ready state. 6, Thread Wakeup: the Notify () method in the object class wakes up a single thread waiting on the objects monitor. If all threads wait on this object, one of the threads will be awakened. The choice is arbitrary and occurs when a decision is made on the implementation. The thread waits on the object's monitor by calling one of the wait methods. The awakened thread continues to execute until the current thread discards the lock on this object. The awakened thread competes in a regular manner with all other threads that are actively synchronizing on the object; For example, the awakened thread does not have a reliable privilege or disadvantage as the next thread to lock this object. A similar method also has a notifyall () that wakes up all the threads waiting on this object monitor. Note: The two methods of suspend () and resume () in thread have been abolished in JDK1.5 and are no longer introduced. Because there is a deadlock tendency.
Six, the common function description
①sleep (Long Millis): Allow the currently executing thread to hibernate (suspend execution) within the specified number of milliseconds
②join (): Refers to waiting for the T thread to terminate.
use the way.
Join is a method of the thread class, which is called directly after the thread is started, that is, join () is "waiting for the thread to terminate", and what needs to be understood here is that the thread is the primary thread that is waiting for the child thread to terminate. That is, the code that follows the join () method is called on the child thread and cannot be executed until the child thread has finished.
Thread t = new Athread (); T.start (); T.join ();
Why use the Join () method
In many cases, the main thread generates and moves the child thread, if there is a large number of time-consuming operations to be performed in a child thread, the main thread will often end before the child thread, but if the main thread finishes processing other transactions, it needs to use the processing result of the child thread, which means that the main thread needs to wait for the execution of the child threads to finish. This is the time to use the join () method. No join.
Package com.zhihua.Thread;
/** * Join is a method of the thread class, which is invoked directly after the thread is started, that is, the join () is "waiting for the thread to terminate", and what needs to be understood here is that the thread is the primary thread that is waiting for the child thread to terminate.
* That is, the code that follows the join () method is invoked on the child thread and cannot be executed until the child thread has finished. * < Replace the function description > <br> * < Please replace for detailed description of the > * * * Why to use the Join () method: * In many cases, the main thread generated and started the child thread, if the child thread to carry out a large number of time-consuming operations, * The main thread is often
will end before the child thread, but if the main thread finishes processing the other transaction, it needs to use the result of the child-threading process, which means that the main thread needs to wait for the child thread to finish execution and then the join () method is used. * @author Caizh * @since [1.0.0] * @version [1.0.0,2017 year April 13] */public class Thread_join extends thread{private
String name;
Public Thread_join (String name) {super (name);
THIS.name = name; The public void Run () {System.out.println () Thread.CurrentThread (). GetName () + thread starts.
");
for (int i = 0; i < 5; i++) {System.out.println ("sub-thread" +name + "run:" + i);
try {sleep (int) math.random () * 10);
catch (Interruptedexception e) {e.printstacktrace (); }} SYSTEM.OUt.println (Thread.CurrentThread (). GetName () + "Thread run end!"); } * * * No JOIN */public static void main (string[] args) {System.out.println (Thread.currentthre AD (). GetName () + "main thread run start."
");
Thread mTh1 = new Thread_join ("A");
Thread mTh2 = new Thread_join ("B");
Mth1.start ();
Mth2.start ();
System.out.println (Thread.CurrentThread (). GetName () + "main thread run end!"); }
}
Output Result:
Main main thread run start!
Main main thread run end!
B thread run start!
Child thread B running: 0
A thread run start!
Sub-thread A runs: 0
child thread B runs: 1
child Thread A runs: 1 child thread A runs: 2 child thread A runs:
3 Child Thread A runs: 4
A thread runs the end!
Child thread B run: 2
child thread B run: 3
child thread B run: 4
B thread run end!
Found mainline Cheng thread early end
Add Join
Package com.zhihua.Thread;
/** * Join is a method of the thread class, which is invoked directly after the thread is started, that is, the join () is "waiting for the thread to terminate", and what needs to be understood here is that the thread is the primary thread that is waiting for the child thread to terminate.
* That is, the code that follows the join () method is invoked on the child thread and cannot be executed until the child thread has finished. * < Replace the function description > <br> * < Please replace for detailed description of the > * * * Why to use the Join () method: * In many cases, the main thread generated and started the child thread, if the child thread to carry out a large number of time-consuming operations, * The main thread is often
will end before the child thread, but if the main thread finishes processing the other transaction, it needs to use the result of the child-threading process, which means that the main thread needs to wait for the child thread to finish execution and then the join () method is used. * @author Caizh * @since [1.0.0] * @version [1.0.0,2017 year April 13] */public class Thread_join extends thread{private
String name;
Public Thread_join (String name) {super (name);
THIS.name = name; The public void Run () {System.out.println () Thread.CurrentThread (). GetName () + thread starts.
");
for (int i = 0; i < 5; i++) {System.out.println ("sub-thread" +name + "run:" + i);
try {sleep (int) math.random () * 10);
catch (Interruptedexception e) {e.printstacktrace (); }} SYSTEM.OUt.println (Thread.CurrentThread (). GetName () + "Thread run end!"); } * * Add join */public static void main (string[] args) {System.out.println (thread.currentthread
(). GetName () + "main thread run start!");
Thread mTh1 = new Thread_join ("A");
Thread mTh2 = new Thread_join ("B");
Mth1.start ();
Mth2.start ();
try {mth1.join ();//main thread primary, MTH1, MTH2 for child thread} catch (Exception e) {} try {
Mth2.join ();
The catch (Exception e) {} System.out.println (Thread.CurrentThread (). GetName () + "main thread run end!");
}
}
Run Result:
main main thread run start!
A thread run start!
Sub-thread A runs: 0
B thread run start!
Child thread B running: 0
child Thread A running: 1
child thread B running: 1
child thread A running: 2
child thread B running: 2 child thread
A running:
3 child Thread A run: 3 child thread
a run: 4
Sub thread B run: 4
A thread run end!
The main thread must wait until the child thread is finished.
③yield (): Pauses the currently executing thread object and executes other threads.
The Thread.yield () method pauses the currently executing thread object and executes other threads. what yield () should do is let the current running thread go back to the operational state to allow other threads with the same priority to get a chance to run. Therefore, the purpose of using yield () is to allow appropriate rotation between threads of the same priority. However, in practice there is no guarantee that the yield () will achieve the concession because the thread of compromise may also be selected again by the thread scheduler. Conclusion: Yield () has never caused a thread to go to a wait/sleep/block state. In most cases, yield () will cause the thread to go from the run state to the operational state, but it may not work. You can see the picture above.
The difference between sleep () and yield ()
The difference between sleep () and yield (): sleep () causes the current thread to stagnate, so the thread that performs sleep () is certainly not executed within the specified time; yield () simply causes the current thread to return to the executable state, so execute yield () Threads are likely to be executed immediately after they enter the executable state.
Sleep method so that the current running threads sleepy for a period of time, into a not-running state, the length of time is set by the program, yield method to make the current thread out of the CPU, but the time is not set. In fact, the yield () method corresponds to the following actions: first detects whether the current thread with the same priority is in the same running state, and if so, hands the CPU to this thread, otherwise, continue running the original thread. So the yield () method is called "concession", which gives the runtime the opportunity to other threads of equal priority.
In addition, the sleep method allows a lower-priority thread to get a chance to run, but when the yield () method executes, the current thread is still in a running state, so it is not possible to give the lower-priority thread some time to gain CPU possession. In a running system, if a higher-priority thread does not call the sleep method and is not blocked by i\o, the lower-priority thread can only wait for all higher-priority threads to run at the end of the opportunity to run.
④setpriority (): Change the priority of the thread.
min_priority = 1
Norm_priority = 5
max_priority = 10 Usage:
Thread4 T1 = new Thread4 ("T1");
THREAD4 t2 = new Thread4 ("T2");
T1.setpriority (thread.max_priority);
T2.setpriority (thread.min_priority);
⑤interrupt (): Do not assume that it is interrupting a thread. It is just a thread that sends an interrupt signal that the thread can throw out when it waits indefinitely (such as a deadlock), and ends the thread, but if you eat the exception, the thread will not break.
⑥wait ()
Obj.wait (), and obj.notify () must be used with synchronized (obj), that is, wait, and notify is for the OBJ lock has been acquired to operate, from a syntactic point of view is obj.wait (), Obj.notify must be in synchronized (OBJ) {...} Statement block. Functionally, wait means that the thread, after acquiring the object lock, actively releases the object lock while the thread sleeps. You cannot continue to acquire an object lock until another thread calls the object's notify () to wake the thread and continue execution. The corresponding notify () is the wake-up action on the object lock. But one thing to note is that after the Notify () call, instead of releasing the object lock immediately, but after the corresponding synchronized () {} statement block executes, and the lock is automatically released, the JVM randomly picks a thread in the threads of the Wait () object lock, gives its object lock, wakes the thread, Continue execution. This provides a synchronized, wake-up operation between threads. Both Thread.Sleep () and object.wait () can suspend the current thread and release CPU control, the main difference being that object.wait () releases the control of the object lock while releasing the CPU.
It is not enough to understand the concept alone, it needs to be tested in the actual example to better understand. For Object.wait (), object.notify () the application of the most classic example, should be a three-way print ABC problem, this is a more classic face questions, the title requirements are as follows:
Create three threads, a thread print 10 times a,b thread print 10 times b,c thread Print 10 times C, require thread to run simultaneously, alternating print 10 times ABC. This problem can be easily solved with the object's Wait (), notify (). The code is as follows:
Package com.zhihua.Thread_Wait;
/** * This is a relatively classic face test questions, the topic requirements are as follows: * Create three threads, a thread print 10 times a,b thread print 10 times b,c thread Print 10 times C, require thread to run simultaneously, alternating print 10 times ABC.
* This problem can be easily solved with the object's Wait (), notify (). * < Replace functional description > <br> * < Please replace with detailed description > * @author Caizh * @since [1.0.0] * @version [1.0.0,2017 year April 13] * * * PU
Blic class Mythreadprinter implements runnable{private String name;
Private Object prev;
Private Object self;
Private Mythreadprinter (String name,object prev,object self) {this.name = name;
This.prev = prev;
This.self = self;
@Override public void Run () {int count = 10; while (count>0) {synchronized (prev) {synchronized (self) {System.out.prin
t (name);
count--;
Self.notify ();
} try{prev.wait (); }catch (interruptedexception e) {e.printstacktrace ();
}}} public static void Main (string[] args) throws Interruptedexceptio
n {Object A = new object ();
Object B = new Object ();
Object c = new Object ();
Mythreadprinter pa = new Mythreadprinter ("A", c,a);
Mythreadprinter PB = new Mythreadprinter ("B", a,b);
Mythreadprinter pc = new Mythreadprinter ("C", b,c);
New Thread (PA). Start (); Thread.Sleep (100);
Make sure that new Thread (PB) is executed in order a, B, and C. Start ();
Thread.Sleep (100);
New Thread (PC). Start ();
Thread.Sleep (100);
}
}
Output results:
Abcabcabcabcabcabcabcabcabcabc
First of all, to explain the overall idea, from a large direction, the problem for the three-thread synchronous wake-up operation, the main purpose is to Threada->threadb->threadc->threada loop execution three threads. In order to control the order in which the threads are executed, you must determine the order in which to wake and wait, so each thread must hold two object locks in order to continue execution. An object lock is a prev, which is the object lock held by the previous thread. Another is the object lock itself. The main idea is that in order to control the order of execution, it is necessary to hold the Prev lock first, and the previous thread to release its own object lock, then to apply for its own object lock, both print, and then first call Self.notify () release its own object lock, wake the next waiting thread, Then call Prev.wait () to release the Prev object lock, terminate the current thread, and wake up again after the loop is over. Run the above code, you can find three threads looping ABC, a total of 10 times. The main process of running a program is that a thread runs first, holds the C,a object lock, releases the A,c lock, and wakes up B. Thread B waits for a lock, then the B lock, then print B, then release the B,a lock, Wake C, thread C wait for the B lock, then apply for C lock, print C, then release the C,b lock, wake a. There seems to be no problem, but if you think about it, you'll find the problem, which is the initial condition, that three threads start in the order of A,b,c, and in the preceding thoughts, a wakes up b,b wake C,c and wakes up a. However, this assumption relies on the sequence of thread scheduling and execution in the JVM.
the difference between wait and sleep
Common Ground:
1. They are all in a multi-threaded environment, can block the specified number of milliseconds at the program's call, and return.
2. Wait () and sleep () can interrupt the paused state of the thread through the interrupt () method, causing the thread to throw interruptedexception immediately.
If thread A wants to end thread B now, you can call the interrupt method on thread B's corresponding threads instance. If thread B is wait/sleep/join at the moment, thread B throws the interruptedexception immediately, and the thread is safely closed by direct return in catch () {}.
It should be noted that the interruptedexception is thrown by the thread itself, not by the interrupt () method. When interrupt () is invoked on a thread, the thread does not throw interruptedexception if it is executing normal code. However, once the thread has entered the wait ()/sleep ()/join (), the interruptedexception is thrown immediately.
different points:
1. Thread class Methods: Sleep (), yield (), etc.
Method of object: Wait () and notify ()
2. Each object has a lock to control synchronous access. The Synchronized keyword can interact with the lock on the object to achieve synchronization of the thread.
The Sleep method does not release the lock, and the wait method frees the lock so that other threads can use the synchronized control block or method.
3. Wait,notify and Notifyall can only be used in synchronous control methods or in synchronized control blocks, while sleep can be used anywhere
So the biggest difference between the sleep () and wait () methods is:
Sleep (), keep object lock, still occupy the lock;
While wait () is sleeping, release the object lock.
However, wait () and sleep () can interrupt the paused state of the thread through the interrupt () method, which causes the thread to throw the interruptedexception immediately (but it is not recommended).
Sleep () method
Sleep () causes the current thread to stagnate (blocking the current thread), giving up the use of the cup, in order to keep the current thread from hogging the CPU resources of the process alone to allow time for other threads to execute;
Sleep () is a static (static) method of the thread class, so he cannot alter the object's machine lock, so when a synchronized is invoked in a block, the thread is dormant, but the machine lock of the object is released, Other threads do not have access to this object (even if sleeping holds object locks).
After the sleep () hibernation time expires, the thread does not necessarily execute immediately, because other threads may be running and are not scheduled to abort execution unless the thread has a higher priority.
Wait () method
The wait () method is a method in the object class, and when a thread executes to the waiting () method, it goes into an object-dependent standby pool while losing (releasing) the object's machine lock (temporarily losing the machine lock, wait (long timeout) After the timeout time, the object lock needs to be returned, and other threads can access it;
Wait () uses notify or notifyalll or specifies sleep time to wake up threads in the current waiting pool.
Wiat () must be placed in the synchronized block, otherwise the "java.lang.IllegalMonitorStateException" exception will be thrown when the program runtime.
Common thread noun interpretationMain thread: The threads generated by the JVM calling program main (). Current thread: This is an easy to confuse concept. Generally refers to the passage of Thread.cur