Thread basics: thread (4) -- basic thread operations in JAVA (below)

Source: Internet
Author: User

Thread basics: thread (4) -- basic thread operations in JAVA (below)
2-2. interrupt Signal

Interrupt, the meaning of the word itself is to interrupt, terminate, block. When a thread receives this signal (command), it sets the self-generated status attribute to "interrupted ",But the thread itself will not terminate immediately. The programmer needs to determine how to perform the next thread activity based on this state attribute.

2-2-1, interrupt and InterruptedException

It is the thread status change chart that has appeared countless times in the article. We already know that the thread can be in a variety of different States after being created: Ready (runable), running, blocking (waiting), death.The thread is not in any state and can receive the interrupt signal.. If the thread is in the blocking status (caused by wait (), wait (time), or sleep) when receiving the InterruptedException signal, the thread will throw an InterruptedException exception:

Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before Z isn? Http:// "target =" _ blank "class =" keylink "> memory + DQo8L2Jsb2NrcXVvdGU + DQo8cD48aW1nIGFsdD0 =" here write picture description "src =" "title =" \ "/>

The following two possible results are displayed when the Thread receives the interrupt signal:Either the isinterrupt attribute in the thread object is set to true, or an InterruptedException exception is thrown. NOTE: If an InterruptedException exception is thrown, The isinterrupt attribute is not set to true..

2-2-2. Sample Code

The following is a test code to describe how interrupt signals work:

Package test. thread. interrupt; public class InterruptProcessor {public static void main (String [] args) throws Exception {// thread one Thread thread threadOne = new Thread (new Runnable () {@ Override public void run () {Thread currentThread = Thread. currentThread (); // The thread does not receive the interrupt signal immediately. // The thread needs to check whether the self-production status is normal and then decide how to proceed. While (! CurrentThread. isInterrupted () {/** print a sentence here, indicating that the loop is always running * but it is not recommended to write code like this in the official system, because there is no interruption (wait, sleep) the infinite loop of is very CPU-consuming **/System. out. println ("Thread One is always running! ");} System. out. println (" thread one ends normally! "+ CurrentThread. isInterrupted () ;}}); // thread two Thread threadTwo = new Thread (new Runnable () {@ Override public void run () {Thread currentThread = thread. currentThread (); while (! CurrentThread. isInterrupted () {synchronized (currentThread) {try {// block currentThread through wait. wait ();} catch (InterruptedException e) {e. printStackTrace (System. out); System. out. println ("thread two ended abnormally due to the interrupt signal! "+ CurrentThread. isInterrupted (); return ;}} System. out. println (" thread two ends normally! ") ;}}); ThreadOne. start (); threadTwo. start (); // you can use the eclipse tool to add an endpoint here to ensure that threadOne and threadTwo have been started. // Of course, you can also use other methods to ensure this. out. println ("two threads are running normally, and now the interrupt signal is triggered"); threadOne. interrupt (); threadTwo. interrupt ();}}

In the above sample code, we have created two threads threadOne and threadTwo. Among them, the threadOne thread runs cyclically without any blocking (although this method is not recommended in the formal environment, we are here to simulate this thread running state ), the isInterrupt attribute value of this thread is detected every time in a loop. If the value is true, the loop is terminated. The other threadTwo thread immediately enters the blocking status after the thread is started, wait for waking (no other thread will actually wake it up to simulate the thread blocking status ).

At this time, we send an interrupt signal to the two threads. The execution results of the two threads are as follows:

Thread One is running all the time! Thread One is running all the time! Thread one ends normally! Truejava. lang. interruptedException at java. lang. object. wait (Native Method) at java. lang. object. wait (Object. java: 503) at test. thread. interrupt. interruptProcessor $ InterruptProcessor. java: 34) at java. lang. thread. run (Unknown Source) thread two ends abnormally due to the interrupt signal! False

The result displayed by the IDE tool shows that the isInterrupt attribute of the threadOne thread is successfully set to true, and the loop ends normally. The threadTwo thread is in the wait () because an exception is thrown after receiving the interrupt signal, the isInterrupt attribute is still false;

2-2-3. Differences between thread. isInterrupted () and Thread. interrupted ()

In Java's basic thread operation method, there are two ways to obtain the isInterrupt attribute of the current thread. One is the object method thread. isInterrupted (), and the other is the static method Thread. interrupted () of the Thread class (). The two methods seem to be the same, but they are actually different. Let's take a look at the source code of the Java Thread class:

publicclass Thread implements Runnable {    ......    public static boolean interrupted() {        return currentThread().isInterrupted(true);    }    public boolean isInterrupted() {        return isInterrupted(false);    }    /**     * Tests if some Thread has been interrupted.  The interrupted state     * is reset or not based on the value of ClearInterrupted that is     * passed.     */    private native boolean isInterrupted(boolean ClearInterrupted);    ......}

We can see that the thread. isInterrupted () of the object method and Thread. interrupted () of the static method are the isInterrupted () method at the underlying layer of JNI. However, the difference is that the ClearInterrupted parameter, the former is false, and the latter is true. I believe that all readers have guessed the meaning. The ClearInterrupted parameter indicates to the operating system layer whether to reset the isInterrupt attribute of the current thread to (recover or clear) after obtaining the status) false.

This means that when the isInterrupt attribute of a thread is successfully set to true, if you use the object method thread. isInterrupted () returns true no matter how many times you obtain the value. However, if you use the static Thread method. when interrupted () is used to obtain the value, only the result obtained for the first time is true. Then, the isInterrupt attribute of the thread is restored to false,In the future, no matter whether you use Thread. interrupted () or thread. isInterrupted (), the obtained results will be false..

2-3. join Operation 2-3-1. Basic operation

The join Operation will make the execution of the two threads orderly. Specifically, if thread A calls the join Operation of thread B, thread A will wait (or wait for A specified length of time) until the execution of thread B is completed (dead. As shown in:

The following is a sample code. In the code, we have created two threads: one is the thread for executing the main method (recorded as mainThread), and the other is the thread named joinThread. Next, we will call the join method of joinThread in mainThread, so that the mainThread will be blocked until the execution of joinThread is complete, and then continue to execute.

Package test. thread. join; import org. apache. commons. logging. log; import org. apache. commons. logging. logFactory; import org. apache. log4j. basicaggregator;/*** this thread is used to test join execution * @ author yinwenjie */public class JoinThread implements Runnable {static {basicaggregator. configure ();}/*** Log */private static Log LOGGER = LogFactory. getLog (JoinThread. class); public static void main (String [] args) thr Ows Exception {/** start a sub-Thread joinThread, and then wait until the sub-Thread joinThread finishes running * this Thread continues to run **/Thread currentThread = Thread. currentThread (); long id = currentThread. getId (); Thread joinThread = new Thread (new JoinThread (); joinThread. start (); try {// wait. After the joinThread execution is completed, the main thread continues to execute joinThread. join (); ("Thread" + id + "continue execution! ");} Catch (InterruptedException e) {e. printStackTrace () ;}@ Override public void run () {Thread currentThread = Thread. currentThread (); long id = currentThread. getId (); ("Thread" + id + "started successfully, ready to enter the waiting state (5 seconds)"); // use the sleep method, the model Thread executes the Business Code. try {Thread. sleep (5000);} catch (InterruptedException e) {LOGGER. error (e. getMessage (), e) ;}// the thread is awakened by ("Thread" + Id + "execution completed! ");}}

The execution result is as follows:

0 [Thread-0] INFO test. thread. join. joinThread-Thread 12 is started successfully and is ready to enter the waiting state (5 seconds) 5002 [Thread-0] INFO test. thread. join. joinThread-thread 12 execution completed! 5002 [main] INFO test. thread. join. JoinThread-thread 1 continues execution!

Note: If the thread that calls the join method receives the interrupt signal, it will also throw an InterruptedException exception.

2-3-2, join (), join (millis) and join (millis, nanos)

In the basic thread operations of Java, join (), join (millis), and join (millis, nanos) can both wait for the target thread, the main difference between the three methods is the waiting time:

Join: It is equivalent to calling join (0). That is, the current call thread can continue to execute until the running of the target thread ends;

Join (millis): The call thread will continue to run no matter whether the execution of the target thread is completed after millis milliseconds;

Join (millis, nanos): After the call thread waits for millis milliseconds + nanos nanoseconds, the current call thread continues to execute no matter whether the target thread is executed successfully or not; in fact, the description of this join method is not accurate: The second parameter nanos is only a reference value (correction value), and only when it is greater than or equal to 500000, the second parameter takes effect (one thousandth of a second ). Please refer to the source code of this method:

public final synchronized void join(long millis, int nanos) throws InterruptedException {    if (millis < 0) {        throw new IllegalArgumentException("timeout value is negative");    }    if (nanos < 0 || nanos > 999999) {        throw new IllegalArgumentException(                            "nanosecond timeout value out of range");    }    if (nanos >= 500000 || (nanos != 0 && millis == 0)) {        millis++;    }    join(millis);}

The above is the source code of the join (millis, nanos) method in JDK1.7. From the source code, we can see that this parameter is meaningful only when nanos is greater than or equal to 500000 nanoseconds. In addition, it does not allow the calling thread to wait precisely, for example, the number of nanoseconds specified by the parameter.

In the modern computer system, it is still difficult to make a high-level language accurate to one second level of control.. You can imagine that the CPU clock speed of 2.4 billion GHz is only times of high and low voltage in one second, and a hardware-level bit operation requires a combination of high and low voltage. This is not difficult to understand why the source code adds a millisecond wait time when the specified number of nanoseconds is greater than or equal to 500000. Therefore, sometimes the information on the network cannot be fully trusted. Only the knowledge that the reader has personally verified is authentic and trustworthy.

2-4. sleep operation

Sleep operation is the most popular method at work. Why? In my opinion, not because most users understand sleep usage scenarios, but because sleep operations are the most obvious method in JAVA basic thread operations.

Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. the thread does not lose ownership of any monitors.

SleepCurrent thread"Enter the blocking status,And will not release the exclusive status of any object lock occupied by this thread. Note:

The current thread is the thread that calls the sleep method. Instead of the target thread to be called. See the following code snippet:
......Thread currentThread = Thread.currentThread();Thread joinThread = new Thread(new SleepThread());joinThread.start();joinThread.sleep(50000);......

Which thread is blocked? CurrentThread or joinThread? Think for 1 second. Those who answered "joinThread" in their minds did not understand the meaning of the sleep method: please pay attention to "current thread ", the blocking status must be "currentThread ".This is why the sleep method is a static method..

The sleep method is not as effective as the wait method: the sleep method does not release the exclusive mode of the object lock occupied by the current thread. See the following code snippet:
Public class Join2Thread implements Runnable {static {BasicConfigurator. configure ();}/*** Log */private static Log LOGGER = LogFactory. getLog (Join2Thread. class); public static void main (String [] args) throws Exception {Thread joinThread1 = new Thread (new Join2Thread (); joinThread1.start (); thread joinThread2 = new Thread (new Join2Thread (); joinThread2.start () ;}@ Override public void run () {// use the sleep method, the model thread executes the Business Code. try {synchronized (Join2Thread. class) {Thread. sleep (Long. MAX_VALUE) ;}} catch (InterruptedException e) {LOGGER. error (e. getMessage (), e );}}}

How many threads can obtain the key of the Join2Thread. class Object lock (exclusive to the preemption of the Join2Thread. class Object lock )?

When joinThread1 checks the object lock, it finds Join2Thread. the class object is exclusive to no other threads, so Join2Thread is obtained. class Object lock exclusive permission, and execute to "Long. MAX_VALUE "; Because sleep does not release any object lock exclusive permission of this joinThread1 thread (Join2Thread will certainly not be released. class Object lock exclusive );

When the joinThread2 thread checks the exclusive permission of the Join2Thread. class Object lock, it is found that it is still occupied by the joinThread1 thread. Therefore, the joinThread2 thread waits in the boundary area and cannot obtain the key of the Join2Thread. class Object lock.

Therefore, there is only one thread that can have the Join2Thread. class Object Lock key: joinThread1.

3. Introduction

Here, we have used three articles to introduce the basic operations of threads in JAVA. Including policy, policyall, wait, join, sleep, and interrupt. With these operations, the reader has been able to operate the thread to switch jobs in a variety of different States. Of course, these methods are not all operations in the JAVA thread, such as destroy, stop, and resume operations, but these operations have been eliminated (because they are not secure ).

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