Java Concurrency Programming: the use of the thread class

Source: Internet
Author: User
Tags object object thread class

First, the state of the 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.

Second, Context switch

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.

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.

Iii. 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 Ms sleep (long millis,int nanoseconds)    // The first parameter is milliseconds, the 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 classTest {Private inti = 10; PrivateObject object =NewObject ();  Public Static voidMain (string[] args)throwsioexception {test test=NewTest (); MyThread Thread1= Test.NewMyThread (); MyThread thread2= Test.NewMyThread ();        Thread1.start ();    Thread2.start (); }               classMyThreadextendsthread{@Override Public voidrun () {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 classTest { Public Static voidMain (string[] args)throwsIOException {System.out.println ("Enter Thread" +Thread.CurrentThread (). GetName ()); Test test=NewTest (); MyThread Thread1= Test.NewMyThread ();        Thread1.start (); Try{System.out.println ("Thread" +thread.currentthread (). GetName () + "Wait");            Thread1.join (); System.out.println ("Thread" +thread.currentthread (). GetName () + "continue"); } Catch(interruptedexception e) {//TODO auto-generated Catch blockE.printstacktrace (); }    }          classMyThreadextendsthread{@Override Public voidrun () {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:

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 classTest { Public Static voidMain (string[] args)throwsioexception {test test=NewTest (); MyThread Thread= Test.NewMyThread ();        Thread.Start (); Try{Thread.CurrentThread (). Sleep (2000); } Catch(Interruptedexception e) {} thread.interrupt (); }          classMyThreadextendsthread{@Override Public voidrun () {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 classTest { Public Static voidMain (string[] args)throwsioexception {test test=NewTest (); MyThread Thread= Test.NewMyThread ();        Thread.Start (); Try{Thread.CurrentThread (). Sleep (2000); } Catch(Interruptedexception e) {} thread.interrupt (); }          classMyThreadextendsthread{@Override Public voidrun () {inti = 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 classTest { Public Static voidMain (string[] args)throwsioexception {test test=NewTest (); MyThread Thread= Test.NewMyThread ();        Thread.Start (); Try{Thread.CurrentThread (). Sleep (2000); } Catch(Interruptedexception e) {} thread.interrupt (); }          classMyThreadextendsthread{@Override Public voidrun () {inti = 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.

classMyThreadextendsthread{Private volatile BooleanIsstop =false; @Override Public voidrun () {inti = 0;  while(!isstop) {i++; }        }                  Public voidSetstop (Booleanstop) {             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:

This article transferred from: http://www.cnblogs.com/dolphin0520/p/3920357.html

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.