Java Concurrency Programming: the use of the thread class

Source: Internet
Author: User
Tags object object volatile

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).

Public enum State {/** * thread ' state ' for a thread which have not yet started.  */NEW,/** * thread state for a runnable thread. A thread in the runnable * The executing of the Java virtual machine but it's may * being waiting for other resour     Ces from the operating system * such as processor.     */RUNNABLE,/** * thread state-a thread blocked waiting for a monitor lock. * A thread in the blocked state was waiting for a monitor lock * to enter A synchronized block/method or * reenter     A synchronized Block/method after calling * {@link object#wait () object.wait}.     */BLOCKED,/** * thread state for a waiting thread. * A thread is in the waiting state due to calling one of the * following methods: * <ul> * <li>{ @link object#wait () object.wait} with no timeout</li> * <li>{@link #join () Thread.Join} with no timeout& lt;/li> * <li>{@link Locksupport#park () locksupport.park}</li> * </ul> * * <p>a thread in the waiting state was waiting for another     Thread to * perform a particular action.  * For example, a thread of that have called <tt>object.wait () </tt> * on an Object are waiting for another Thread to call * <tt>object.notify () </tt> or <tt>object.notifyall () </tt> on * This Object .     A thread that have called <tt>thread.join () </tt> * is waiting for a specified the thread to terminate.     */Waiting,/** * thread state is a waiting thread with a specified waiting time. * A thread is in the timed waiting state due to calling one of * the following methods with A specified positive Waiti Ng Time: * <ul> * <li>{@link #sleep thread.sleep}</li> * <li>{@link object#wait (lo   ng) object.wait} with timeout</li> * <li>{@link #join (Long) Thread.Join} with timeout</li> *<li>{@link Locksupport#parknanos locksupport.parknanos}</li> * <li>{@link LockSupport#parkUntil Lo cksupport.parkuntil}</li> * </ul> * * timed_waiting,/** * Thread state for a terminated thre     Ad.     * The thread has completed execution. */TERMINATED;}

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 the user actively lets the thread sleep (after a certain amount of sleep), the user actively lets the thread wait, or is blocked by the synchronization block. There are multiple states: timewaiting (sleep or wait for a certain time), waiting (waiting to be awakened), blocked (blocking).

The thread dies when a sudden interruption (throwing an exception) or a child task is completed.

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 current thread's running state needs to be saved during the switchover so that it can continue to run until the next switch back. To give a simple example: for 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 switching back to execute thread A, we do not want thread A to read from the beginning of the file, we want to start from the last pause to continue reading, This requires knowing where the last pause was.

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.

To put it simple: context switching for threads is actually the process of storing and recovering CPU state, which enables thread execution to resume execution from a breakpoint.

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:

public class Thread implements Runnable {/* Make sure registernatives is the first thing <clinit> does. */PR    ivate static native void Registernatives ();    static {registernatives ();    } private volatile String name;    private int priority;    Private Thread THREADQ;    Private long eetop; /* Whether or not to single_step the this thread.    */Private Boolean single_step; /* Whether or not, the thread is a daemon thread.    */Private Boolean daemon = false;    /* JVM state */Private Boolean stillborn = false; /* What'll be run.    */private Runnable target;    /* The group of this thread */private threadgroup Group;    /* The context ClassLoader for this thread */private ClassLoader contextclassloader;    /* The inherited accesscontrolcontext of this thread */private AccessControlContext inheritedaccesscontrolcontext; /* for autonumbering anonymous threads. */private static int Threadinitnumber;    private static synchronized int nextthreadnum () {return threadinitnumber++; }/* ThreadLocal values pertaining to this thread. This map was maintained * by the ThreadLocal class. */Threadlocal.threadlocalmap threadlocals = null;}

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 = ten;    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:

I:11 thread Thread-0 enters sleep thread Thread-0 sleep end i:12i:13 thread Thread-1 go to sleep thread Thread-1 sleep end i:14

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 you are calling the parameterless join method, wait for the thread to finish executing, and if you are calling a join method that specifies a time parameter, wait a certain amount of time.

Take a look at the following example:

Import Java.io.ioexception;public class Test {public static void main (string[] args) throws IOException {Syste        M.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 block E.printstacktrace (); }} class MyThread extends thread{@Override public void Run () {System.out.println ("Enter Thread:"            +thread.currentthread (). GetName ());            try {thread.currentthread (). Sleep (5000); } catch (Interruptedexception e) {//Todo:handle exception} System.out.println ("Thread "+thread.currentthread (). GetName () +" execution Complete "); }    }}

Output Result:

Enter thread main thread main waiting to enter thread Thread-0 thread Thread-0 Execute thread main continue execution

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:

Public final synchronized void join (long Millis)    throws interruptedexception {        long base = System.currenttimemillis ();        Long now = 0;        if (Millis < 0) {            throw new IllegalArgumentException ("Timeout value is negative");        }        if (Millis = = 0) {            while (isAlive ()) {                Wait (0),            }        } else {while            (IsAlive ()) {                Long delay = mil Lis-now;                if (delay <= 0) {break                    ;                }                Wait (delay);                now = System.currenttimemillis ()-Base;}}}        

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:

Import Java.io.ioexception;public class Test {public    static void Main (string[] args) throws IOException {        Test te st = 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 State ");                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:

Go to sleep get interrupted exception Run method execution complete

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 volatile 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:

Java Concurrency Programming: the use of the thread class

Related Article

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.