Java并发——yield()、sleep() 和 join() 方法
在本文中,我们将了解Java中的 yield()、join() 和 sleep() 方法以及这三者之间的基本区别是什么。首先,我们将看到所有这三种方法的基本介绍,然后我们将这三种方法进行比较。
我们可以通过使用 Thread 类的以下方法之一来阻止线程的执行。所有三种方法都将用于阻止线程执行。
1.yield()方法
假设有三个线程 t1、t2 和 t3。线程 t1 获得处理器并开始执行,线程 t2 和 t3 处于就绪/可运行状态。线程 t1 的完成时间为 5 小时,t2 的完成时间为 5 分钟。由于 t1 将在 5 小时后完成执行,因此 t2 必须等待 5 小时才能完成 5 分钟的工作。在一个线程花费太多时间来完成其执行的这种情况下,我们需要一种方法来防止在有重要事情未决时执行介于两者之间的线程。 yield() 帮助我们这样做。
yield()基本上意味着线程没有做任何特别重要的事情,如果需要运行任何其他线程或进程,它们应该运行。否则,当前线程将继续运行。
使用yield方法:
- 每当线程调用Java.lang.Thread.yield方法时,都会向线程调度程序提示它已准备好暂停其执行。线程调度程序可以随意忽略此提示。
- 如果任何线程执行了 yield 方法,线程调度程序会检查是否有任何线程与该线程具有相同或高优先级。如果处理器发现任何具有更高或相同优先级的线程,则它将当前线程移动到就绪/可运行状态并将处理器交给另一个线程,如果没有,当前线程将继续执行。
- 一旦一个线程执行了 yield 方法并且有许多相同优先级的线程在等待处理器,那么我们就无法指定哪个线程将首先获得执行机会。
- 执行yield方法的线程会从Running状态进入Runnable状态。
- 一旦线程暂停执行,我们无法指定它何时再次获得机会,这取决于线程调度程序。
- 如果我们使用 yield 方法,底层平台必须提供对抢占式调度的支持。
2. sleep() 方法
此方法使当前执行的线程休眠指定的毫秒数,具体取决于系统计时器和调度程序的精度和准确性。
句法:
// sleep for the specified number of milliseconds
public static void sleep(long millis) throws InterruptedException
//sleep for the specified number of milliseconds plus nano seconds
public static void sleep(long millis, int nanos)
throws InterruptedException
Java
// Java program to illustrate
// sleep() method in Java
import java.lang.*;
public class SleepDemo implements Runnable {
Thread t;
public void run()
{
for (int i = 0; i < 4; i++) {
System.out.println(
Thread.currentThread().getName() + " "
+ i);
try {
// thread to sleep for 1000 milliseconds
Thread.sleep(1000);
}
catch (Exception e) {
System.out.println(e);
}
}
}
public static void main(String[] args) throws Exception
{
Thread t = new Thread(new SleepDemo());
// call run() function
t.start();
Thread t2 = new Thread(new SleepDemo());
// call run() function
t2.start();
}
}
Java
// Java program to illustrate join() method in Java
import java.lang.*;
public class JoinDemo implements Runnable {
public void run()
{
Thread t = Thread.currentThread();
System.out.println("Current thread: "
+ t.getName());
// checks if current thread is alive
System.out.println("Is Alive? " + t.isAlive());
}
public static void main(String args[]) throws Exception
{
Thread t = new Thread(new JoinDemo());
t.start();
// Waits for 1000ms this thread to die.
t.join(1000);
System.out.println("\nJoining after 1000"
+ " milliseconds: \n");
System.out.println("Current thread: "
+ t.getName());
// Checks if this thread is alive
System.out.println("Is alive? " + t.isAlive());
}
}
Thread-1 0
Thread-0 0
Thread-0 1
Thread-1 1
Thread-0 2
Thread-1 2
Thread-1 3
Thread-0 3
Note:
- Based on the requirement we can make a thread to be in a sleeping state for a specified period of time
- Sleep() causes the thread to definitely stop executing for a given amount of time; if no other thread or process needs to be run, the CPU will be idle (and probably enter a power-saving mode).
3.join()方法
Thread 实例的 join() 方法用于将线程执行的开始连接到另一个线程执行的结束,这样一个线程直到另一个线程结束才开始运行。如果在 Thread 实例上调用 join(),则当前正在运行的线程将阻塞,直到 Thread 实例完成执行。 join() 方法最多等待这么多毫秒,以使该线程终止。超时 0 意味着永远等待
句法:
// waits for this thread to die.
public final void join() throws InterruptedException
// waits at most this much milliseconds for this thread to die
public final void join(long millis)
throws InterruptedException
// waits at most milliseconds plus nanoseconds for this thread to die.
The java.lang.Thread.join(long millis, int nanos)
Java
// Java program to illustrate join() method in Java
import java.lang.*;
public class JoinDemo implements Runnable {
public void run()
{
Thread t = Thread.currentThread();
System.out.println("Current thread: "
+ t.getName());
// checks if current thread is alive
System.out.println("Is Alive? " + t.isAlive());
}
public static void main(String args[]) throws Exception
{
Thread t = new Thread(new JoinDemo());
t.start();
// Waits for 1000ms this thread to die.
t.join(1000);
System.out.println("\nJoining after 1000"
+ " milliseconds: \n");
System.out.println("Current thread: "
+ t.getName());
// Checks if this thread is alive
System.out.println("Is alive? " + t.isAlive());
}
}
Current thread: Thread-0
Is Alive? true
Joining after 1000 milliseconds:
Current thread: Thread-0
Is alive? false
Note:
- If any executing thread t1 calls join() on t2 i.e; t2.join() immediately t1 will enter into waiting state until t2 completes its execution.
- Giving a timeout within join(), will make the join() effect to be nullified after the specific timeout.
yield()、join()、sleep()方法比较
Property | yield() | join() | sleep() |
---|---|---|---|
Purpose | If a thread wants to pass its execution to give chance to remaining threads of the same priority then we should go for yield() | If a thread wants to wait until completing of some other thread then we should go for join() | If a thread does not want to perform any operation for a particular amount of time, then it goes for sleep() |
Is it overloaded? | NO | YES | YES |
Is it final? | NO | YES | NO |
Is it throws? | NO | YES | YES |
Is it native? | YES | NO | sleep(long ms)->native & sleep (long ms, int ns)-> non native |
Is it static? | YES | NO | YES |