Java中阻止线程执行的方法

原文地址: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 Java
import java.lang.*;

// MyThread extending Thread
class MyThread extends Thread {
    public void run() {
        for (int i=0; i<5 ; i++)
            System.out.println(Thread.currentThread().getName() + " in control");
    }
}

// Driver Class
public 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 control
Thread-0 in control
Thread-0 in control
Thread-0 in control
Thread-0 in control
main in control
main in control
main in control
main in control
main 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 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();
    }
}

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 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" + " 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-0
Is Alive? true

Joining after 1000 mili seconds: 

Current thread: Thread-0
Is alive? false

注意:

  • 如果任意一个执行的线程t1在t2上调用join(),例如t2.join(),那么t1会马上进入等待状态,直到t2完成执行。
  • 已知在join()中产生了超时,那么这将使得join()的作用在超时之后被抵消。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值