The difference between yield and join methods in Java threads

Source: Internet
Author: User


For a long time, multithreading problems have been favored by interviewers. While I personally think that few of us can really get a chance to develop complex multithreaded applications (I've got a chance in the last seven years), understanding multithreading is useful for increasing your confidence. Before, I discussed the difference between the wait () and sleep () methods, and this time I will discuss the difference between the join () and the yield () methods. Frankly speaking, I have not actually used any of these methods, so if you feel that there is something inappropriate, please ask for a discussion.


A little background in Java thread scheduling


In a variety of threads, a Java virtual machine must implement a priority-based scheduler. This means that each thread in a Java program is assigned a certain priority, expressed as a positive integer within the defined range. The priority can be changed by the developer. The Java Virtual machine does not change its priority even if the thread has been running for a certain amount of time


The priority value is important because the convention between the Java Virtual machine and the lower-level operating system is that the operating system must select the Java thread with the highest priority to run. So we say Java implements a priority-based scheduler. The scheduler is implemented in a prioritized manner, which means that when a thread with a higher priority arrives, it will be interrupted (preempted) regardless of whether the low-priority thread is running. This Convention is not always the case for the operating system, which means that the operating system may sometimes choose to run a lower-priority thread. (I hate multithreading for this, because it doesn't guarantee anything)


Note that Java does not restrict threads to run on a time slice, but most operating systems have this requirement. Confusion often arises in terminology: preemption is often confused with time slices. In fact, preemption means that only threads with high priority can take precedence over low-priority threads, but they cannot preempt each other when the threads have the same priority. They are usually controlled by time slices, but this is not the Java requirement.


Understanding the priority of a thread


Next, understanding thread prioritization is an important step in multithreaded learning, especially in the work process of understanding the yield () function.


Remember that when the priority of a thread is not specified, all threads carry a normal priority.

The priority can be specified in a range from 1 to 10. 10 represents the highest priority, 1 represents the lowest priority, and 5 is the normal priority.

Remember that the highest priority thread is given priority at execution time. However, there is no guarantee that the thread will enter the running state at startup.

Threads that are currently running may always have a higher priority than the threads in the thread pool that are waiting for a chance to run.

The scheduler determines which thread is executed.

T.setpriority () is used to set the priority of the thread.

Remember that the thread priority should be set before the threads Start method is called.

You can use constants, such as Min_priority,max_priority,norm_priority, to set the priority

Now, when we have some understanding of thread scheduling and thread prioritization, let's go into the topic.


Yield () method


In theory, yield means letting go, giving up, surrendering. A thread that calls the yield () method tells the virtual machine that it is willing to let other threads occupy its place. This indicates that the thread is not doing something urgent. Note that this is only a hint and is not guaranteed to have no effect.


The yield () in Thread.java is defined as follows:


/**

* A hint to the scheduler, the current thread was willing to yield it current use of a processor. The scheduler is free to ignore

* This hint. Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilize a CPU.

* Its use should is combined with detailed profiling and benchmarking to ensure that it actually have the desired effect.

*/

public static native void yield ();


Let's list some important points about the above definition:


Yield is a static native (native) method

Yield tells the currently executing thread to pass the run opportunity to a thread in the thread pool that has the same priority.

Yield does not guarantee that the currently running thread will quickly transition to a running state

It allows only one thread to move from the running state to the operational state, rather than waiting or blocking the state

Yield () method Use example


In the following example program, I randomly created two threads called producers and consumers. The producer is set to the minimum priority and the consumer is set to the highest priority. In the case of Thread.yield () comments and non-annotations, I will run the program separately. The yield () method is not called, although the output sometimes changes, but usually the consumer line first prints out and then the producer.


When the yield () method is called, two threads print sequentially, then give the execution opportunity to the other party, and continue to do so.


Package test.core.threads;

public class Yieldexample

{

public static void Main (string[] args)

{

Thread producer = new producer ();

Thread consumer = new Consumer ();

Producer.setpriority (thread.min_priority); Min Priority

Consumer.setpriority (thread.max_priority); Max Priority

Producer.start ();

Consumer.start ();

}

}

Class Producer extends Thread

{

public void Run ()

{

for (int i = 0; i < 5; i++)

{

System.out.println ("I am producer:produced Item" + i);

Thread.yield ();

}

}

}

Class Consumer extends Thread

{

public void Run ()

{

for (int i = 0; i < 5; i++)

{

System.out.println ("I am consumer:consumed Item" + i);

Thread.yield ();

}

}

}

The output of the above program without invoking the yield () method

I am consumer:consumed Item 0

I am consumer:consumed Item 1

I am consumer:consumed Item 2

I am consumer:consumed Item 3

I am consumer:consumed Item 4

I am producer:produced Item 0

I am producer:produced Item 1

I am producer:produced Item 2

I am producer:produced Item 3

I am producer:produced Item 4

The output of the above program in the case of invoking the yield () method:

I am producer:produced Item 0

I am consumer:consumed Item 0

I am producer:produced Item 1

I am consumer:consumed Item 1

I am producer:produced Item 2

I am consumer:consumed Item 2

I am producer:produced Item 3

I am consumer:consumed Item 3

I am producer:produced Item 4

I am consumer:consumed Item 4


Join () method


The method join () method of a thread instance allows one thread to execute after another thread has finished. If the join () method is called on a thread instance, the currently running thread will block until the thread instance finishes executing.

Waits for the thread to die.

Public final void Join () throws Interruptedexception

Setting a timeout within the join () method causes the effect of the join () method to be invalid after a specific timeout. When the time-out occurs, the main method and the task thread request to run are equal. However, when sleep is involved, the join () method relies on the operating system timing, so you should not assume that the join () method will wait for the time you specify. Like Sleep,join responds to interrupts by throwing interruptedexception.


Join () method Use example


Package test.core.threads;

public class Joinexample

{

public static void Main (string[] args) throws Interruptedexception

{

Thread t = new Thread (new Runnable ()

{

public void Run ()

{

SYSTEM.OUT.PRINTLN ("first task started");

System.out.println ("Sleeping for 2 Seconds");

Try

{

Thread.Sleep (2000);

} catch (Interruptedexception e)

{

E.printstacktrace ();

}

SYSTEM.OUT.PRINTLN ("first task completed");

}

});

thread T1 = new Thread (new Runnable ()

{

public void Run ()

{

SYSTEM.OUT.PRINTLN ("Second task completed");

}

});

T.start (); Line 15

T.join (); Line 16

T1.start ();

}

}

Output:

First task started

Sleeping for 2 seconds

First task completed

Second Task completed

This is a small but very important concept. Let me know what you think in the comments section.


The difference between yield and join methods in Java threads

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.