Java Concurrency Programming: the use of the thread class
In the previous 2 articles, we talked about the origins of threads and processes, and how to create threads and processes in Java. Today we will learn about the thread class, before learning the thread class, first introduce the threading-related knowledge: Several states of the thread, context switches, and then describes the use of methods in the thread class.
The following is the directory outline for this article:
I. The state of a thread
Two. Context Switches
Three. Methods in the Thread class
Four. Three methods related to the thread class in the object class Wait,notify,notifyall
If there is any difference, please understand and welcome the criticism.
Please respect the author's labor results, reproduced please indicate the original link:
Http://www.cnblogs.com/dolphin0520/p/3920357.html
I. The state of a thread
Before we formally learn the specific methods in the thread class, let's look at the state of the thread, which will help to understand the methods in the thread class.
Threads go through a number of States, from creation to eventual extinction. In general, threads include the following states: Create (new), Ready (runnable), run (running), block (blocked), time waiting, waiting, extinction (dead).
When a new thread is needed to execute a subtask, a thread is created. However, after a thread is created, it is not immediately ready because the thread is running with some conditions (such as memory resources, a blog post in the previous JVM memory area that knows the program counter, the Java stack, and the local method stack are thread-private, so you need to allocate a certain amount of memory space to the thread). Only if all the conditions required for the thread to run are met, the ready state is entered.
When the thread is in a ready state, it does not mean that the CPU execution time is immediately available, and perhaps the CPU is doing something else, so it waits. When the CPU execution time is obtained, the thread actually goes into the running state.
While the thread is running, there may be several reasons why the current thread does not continue to run, such as when the user proactively causes the thread to sleep (after a certain amount of sleep), the user actively lets the thread wait, or is blocked by the synchronization block, which corresponds to multiple states: time Waiting (sleep or wait for a certain event), waiting (waiting to be awakened), blocked (blocking).
When a sudden interruption or completion of a sub-task, the thread will be extinct.
The following diagram depicts the state of a thread from creation to extinction:
In some tutorials, blocked, waiting, and time waiting are collectively known as blocking states, which is also possible, except that I want to associate the state of the thread with the method call in Java, so the waiting and time waiting two states are separated.
Two. Context Switches
For a single-core CPU (for multicore CPUs, this is understood here as a core), the CPU can only run one thread at a time, and when the process of running one thread goes to run another thread, this is called a thread-context switch (similar to a process).
Since it is possible that the task of the front-end process is not completed, the running state of the thread needs to be saved during the switchover so that it can continue to run until the next switch back. To give a simple example: a thread A is reading the contents of a file, is reading half of the file, the need to pause thread A, go to execute thread B, when the switch back to execute thread A, we do not want thread A again from the beginning of the file to read.
So you need to record the running state of thread A, what data is logged? Because the next time you need to know which command the current thread has executed before, you need to log the value of the program counter, and if the thread is suspended while a calculation is in progress, the next time you continue execution you need to know what the value of the variable was when it was suspended, so you need to record the status of the CPU register. So in general, the program counters, CPU register status and other data are recorded during thread context switching.
While multi-threading can improve the efficiency of task execution, there are also some overhead costs associated with thread switching, and multiple threads can lead to increased system resource usage, so be aware of these factors in multithreaded programming.
Three. Methods in the Thread class
By looking at the source code of the Java.lang.Thread class:
The thread class implements the Runnable interface, in the thread class, some of the more critical properties, such as name is the name of the thread, and the thread name can be specified by the parameters in the constructor of the thread class. Priority indicates the thread's precedence (maximum value is 10, minimum value is 1, default is 5), daemon indicates whether the thread is a daemon thread, and target represents the task to perform.
The following are common methods in the thread class:
Here are a few ways to relate to the running state of a thread:
1) Start method
Start () is used to start a thread, and when the Start method is called, the system opens a new thread to execute the user-defined subtask, in which the appropriate thread is assigned the required resources.
2) Run method
The run () method does not require a user to invoke, and when a thread is started by the Start method, when the thread obtains the CPU execution time, it enters the Run method body to perform the specific task. Note that inheriting the thread class must override the Run method and define the specific task to be performed in the Run method.
3) Sleep method
There are two overloaded versions of the Sleep method:
Sleep (long Millis) //parameter is milliseconds sleep (long millis,int nanoseconds) ///First parameter is millisecond, second parameter is nanosecond
Sleep is the equivalent of having a thread sleeping, handing over the CPU, and allowing the CPU to perform other tasks.
However, it is important to note that the sleep method does not release the lock, which means that if the current thread holds a lock on an object, other threads cannot access the object even if the sleep method is called. See the following example to make it clear:
public class Test {private int i = 10;private Object object = new Object (); public static void Main (string[] args) throws IOException { test test = new Test (); MyThread thread1 = Test.new MyThread (); MyThread thread2 = Test.new MyThread (); Thread1.start (); Thread2.start (); } Class MyThread extends thread{ @Override public void Run () { synchronized (object) {i++; System.out.println ("I:" +i); try {System.out.println ("thread" +thread.currentthread (). GetName () + "Go to Sleep"); Thread.CurrentThread (). Sleep (10000);} catch (Interruptedexception e) {///Todo:handle exception}system.out.println ("Thread" +thread.currentthread (). GetName () + " End of Sleep "); i++; System.out.println ("I:" +i);}}}
Output Result:
As can be seen from the above results, when Thread-0 goes to sleep, Thread-1 does not perform specific tasks. Thread-1 only begins execution when the object lock is Thread-0 released when Thread-0 is finished executing.
Note that if you call the Sleep method, you must either catch the Interruptedexception exception or throw the exception to the upper layer. When a thread sleeps at full time, it does not necessarily get executed immediately, because the CPU may be performing other tasks at this time. So calling the sleep method is equivalent to getting the thread into a blocking state.
4) Yield method
Invoking the yield method causes the current thread to hand over the CPU permissions, allowing the CPU to execute other threads. It is similar to the sleep method and does not release the lock. However, yield does not control the specific time to hand over the CPU, and the yield method only allows threads with the same priority to have the opportunity to get CPU execution time.
Note that calling the yield method does not cause the thread to go into a blocking state, but instead allows the thread to return to the ready state, which only needs to wait for the CPU execution time to be fetched again, which is not the same as the sleep method.
5) Join method
There are three overloaded versions of the Join method:
Join () Join (long Millis)/ /parameter is millisecond join (long millis,int nanoseconds) ///First parameter is millisecond, second parameter is nanosecond
If the Thread.Join method is called in the main thread, the main method waits for the thread thread to complete or wait for a certain amount of time. If the call is a parameterless join method, wait for the thread to finish executing and wait for a certain event if the join method that specified the time parameter is called.
Take a look at the following example:
public class Test {public static void Main (string[] args) throws IOException { System.out.println ("Enter thread" + Thread.CurrentThread (). GetName ()); Test test = new test (); MyThread thread1 = Test.new MyThread (); Thread1.start (); try { System.out.println ("Thread" +thread.currentthread (). GetName () + "Wait"); Thread1.join (); SYSTEM.OUT.PRINTLN ("Thread" +thread.currentthread (). GetName () + "continue execution");} catch (Interruptedexception e) {//TODO auto-generated catch Blocke.printstacktrace ();} } Class MyThread extends thread{ @Override public void Run () { System.out.println ("Enter thread" + Thread.CurrentThread (). GetName ()); try { thread.currentthread (). Sleep (n),} catch (Interruptedexception e) {//Todo:handle exception} SYSTEM.OUT.PRINTLN ("Thread" +thread.currentthread (). GetName () + "execution complete");}}}
Output Result:
As you can see, when the Thread1.join () method is called, the main thread enters the wait and waits for the thread1 to execute before continuing.
Actually calling the join method is called the wait method of object, which can be learned by viewing the source:
The wait method causes the thread to go into a blocking state, releasing the lock that the thread occupies and handing over the CPU execution permissions.
Because the wait method causes the thread to release the object lock, the Join method also causes the thread to release locks held on an object. The specific wait method is used in the following article.
6) Interrupt Method
Interrupt, as the name implies, is the meaning of interruption. Calling the interrupt method alone can cause a blocked thread to throw an exception, which can be used to break a thread that is in a blocking state, and to stop a running thread by using the interrupt method and the Isinterrupted () method.
Let's look at an example:
public class Test {public static void Main (string[] args) throws IOException { test test = new Test (); MyThread thread = Test.new MyThread (); Thread.Start (); try {thread.currentthread (). Sleep (),} catch (Interruptedexception e) {} thread.interrupt (); } Class MyThread extends thread{ @Override public void Run () { try { System.out.println ("Go to Sleep"); Thread.CurrentThread (). Sleep (10000); System.out.println ("Sleep Complete");} catch (Interruptedexception e) {System.out.println ("Get interrupt Exception"); System.out.println ("Run Method execution Complete");}}}
Output Result:
As you can see from here, you can break a blocked thread by using the interrupt method. Can you break a non-blocking thread? Look at the following example:
public class Test {public static void Main (string[] args) throws IOException { test test = new Test (); MyThread thread = Test.new MyThread (); Thread.Start (); try {thread.currentthread (). Sleep (),} catch (Interruptedexception e) {} thread.interrupt (); } Class MyThread extends thread{ @Override public void Run () { int i = 0; while (I<integer.max_value) { System.out.println (i+ "while loop"); i++;}}}}
Running the program will find that the while loop runs until the value of the variable I exceeds integer.max_value. Therefore, calling the interrupt method directly does not interrupt a running thread.
However, if the Mate isinterrupted () is able to break the running thread, because calling the interrupt method is equivalent to having the interrupt flag position true, you can call isinterrupted () to determine whether the interrupt flag is set to execute in the thread break. For example, the following code:
public class Test {public static void Main (string[] args) throws IOException { test test = new Test (); MyThread thread = Test.new MyThread (); Thread.Start (); try {thread.currentthread (). Sleep (),} catch (Interruptedexception e) {} thread.interrupt (); } Class MyThread extends thread{ @Override public void Run () { int i = 0; while (!isinterrupted () && i<integer.max_value) { System.out.println (i+ "while loop"); i++;}}}}
Running will find that after printing several values, the while loop stops printing.
In general, however, it is not recommended to break threads in this way, typically adding an attribute isstop in the Mythread class to flag whether to end the while loop and then to determine the value of isstop in the while loop.
Class MyThread extends thread{ private Boolean isstop = false; @Override public Void Run () { int i = 0; while (!isstop) { i++; } } public void Setstop (Boolean stop) { this.isstop = stop; } }
You can then terminate the while loop outside by calling the Setstop method.
7) Stop method
The Stop method is already an obsolete method, and it is an unsafe method. Because calling the Stop method terminates the call to the Run method directly and throws a Threaddeath error, if the thread holds an object lock, the lock is completely released, causing the object state to be inconsistent. So the Stop method is basically not going to be used.
8) Destroy method
The Destroy method is also an obsolete method. Basic will not be used.
Here are a few ways to relate to thread properties:
1) getId
Used to get the thread ID
2) GetName and SetName
Used to get or set the thread name.
3) GetPriority and SetPriority
Used to get and set thread priority.
4) Setdaemon and Isdaemon
Used to set whether the thread is a daemon thread and whether the thread is a daemon thread.
The difference between a daemon thread and a user thread is that the daemon relies on the thread that created it, and the user thread does not depend on it. As a simple example: if you create a daemon thread in the main thread, when the main method finishes running, the daemon thread will die as well. The user thread does not, and the user thread runs until it finishes running. In the JVM, a garbage collector thread is the daemon thread.
The thread class has a more commonly used static method, CurrentThread (), to get the current thread.
The most of the methods in the thread class have been mentioned above, so how does a method call in the thread class cause the thread state to change? The following picture is an improvement on the above diagram:
Resources:
The idea of Java programming
Http://www.cnblogs.com/DreamSea/archive/2012/01/11/JavaThread.html#navigation
Http://www.blogjava.net/vincent/archive/2008/08/23/223912.html
http://iteye.blog.163.com/blog/static/1863080962012111424544215/
http://blog.csdn.net/lifei128/article/details/20363257