Java中阻止线程执行的方法

来源:互联网 发布:统计学毕业论文数据 编辑:程序博客网 时间:2024/06/05 10:37

原文地址:http://www.geeksforgeeks.org/java-concurrency-yield-sleep-and-join-methods/

我们可以通过Thread类中的下面几个方法阻止线程的执行。

yield()

假设有三个线程t1,t2和t3。线程t1得到了处理器并且开始执行,线程t2和t3在等待/可执行状态。t1需要5小时可以完成,t2需要5分钟可以完成。因为t1在5个小时以后才能完成,那么t2想要完成5分钟的任务那就得等5个小时。在这种情景下一个线程为了完成它的执行就花费的时间太久了,我们需要一个方法在有正要的事情发生的时候可以阻止线程的执行。yield()就可以帮我们做这样的事情。

yield()实际上就是当一个线程所执行的任务不是那么重要的时候,这时候其他的线程或者进程需要执行了,那么就让这些线程或者进程执行。否则的话,当前的线程继续执行。


这里写图片描述

yield的用法

  • 无论啥时候一个线程调用java.lang.Thread.yield方法,它都会通知线程调度程序准备暂停线程的执行。线程调度器可以随意忽略这样的提示。
  • 如果优先从执行了yield方法,线程调度程序就会检查是否有线程比它有相同的或者更高的优先级。如果处理器找到了与它相同或者更高优先级的线程,那么处理器就会移除当前线程到准备/可执行状态,并将处理器分配给其他线程,如果没找到,那就当前线程继续执行呗。
语法
public static native void yield()
// Java program to illustrate yield() method in Javaimport java.lang.*;// MyThread extending Threadclass MyThread extends Thread {    public void run() {        for (int i=0; i<5 ; i++)            System.out.println(Thread.currentThread().getName() + " in control");    }}// Driver Classpublic class yieldDemo {    public static void main(String[] args) {        MyThread t = new MyThread();        t.start();        for (int i = 0; i < 5; i++) {            // Control passes to child thread            Thread.yield();            // After execution of child Thread            // main thread takes over            System.out.println(Thread.currentThread().getName() + " in control");        }    }}

输出:

Thread-0 in controlThread-0 in controlThread-0 in controlThread-0 in controlThread-0 in controlmain in controlmain in controlmain in controlmain in controlmain in control

输出的结果可能在不同的机器上不一样,但是yield()过的线程是比其他线程执行的机会要高的,因为main线程总是暂停它的执行,并给相同优先级的子线程机会执行。

注意

  • 一旦一个线程执行了yield方法,那么就会有许多优先级相同的线程都在等待处理器,那么我们就不能指定那个线程有最先执行的机会了。
  • 执行了yield方法的线程将从运行状态进入可运行状态。
  • 一旦一个线程暂停了它的执行,那么我们就不能干预了,它的再次执行就全看线程调度程序了。
  • 如果我们要用yield方法,那么底层平台就必须得提供抢先调度(preemptive scheduling)的支持。

sleep()

这个方法会让当前执行的程序睡眠指定的时间,这个受限于系统时间和调度程序的准确度。

语法

//  睡眠指定的毫秒数public static void sleep(long millis) throws InterruptedException//睡眠指定的毫秒数+纳秒public static void sleep(long millis, int nanos) throws InterruptedException
// Java program to illustrate// sleep() method in Javaimport 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();    }}

yield() vs sleep()

yield()指的是线程在没有做特别重要的任务的时候,如果其他线程或者进程需要执行,那么就会执行。否则当前线程继续执行就行了。

sleep()是说线程确实需要停止执行指定的一段时间,如果没有其他的线程或者进程需要执行,那么CPU将处于空闲(也可能进入省电模式)

join()

Thread实例的join方法是用于连接开始一个线程的执行到结束另一个线程的执行,这样线程就不用在另一个线程执行完了才开始执行。如果一个Thread实例调用join(),那么当前执行的线程就会受阻知道这个线程的智力执行完毕。

join()方法最多等到这个线程死亡,将超时设为0意思就是永不超时或者永远等待。

语法
// 等待线程死亡public final void join() throws InterruptedException// 最多等待这么多毫秒public final void join(long millis) throws InterruptedException// 最多等待这么多毫秒+纳秒The java.lang.Thread.join(long millis, int nanos)
// Java program to illustrate join() method in Javaimport 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" + " mili seconds: \n");        System.out.println("Current thread: " + t.getName());        // Checks if this thread is alive        System.out.println("Is alive? " + t.isAlive());    }}

输出:

Current thread: Thread-0Is Alive? trueJoining after 1000 mili seconds: Current thread: Thread-0Is alive? false

注意:

  • 如果任意一个执行的线程t1在t2上调用join(),例如t2.join(),那么t1会马上进入等待状态,直到t2完成执行。
  • 已知在join()中产生了超时,那么这将使得join()的作用在超时之后被抵消。
阅读全文
0 0