Java中的join(),yield()解读

版权声明:分享,转载原创文章,麻烦注明一下出处~谢谢 https://blog.csdn.net/sc9018181134/article/details/82289605

前言:

多线程中让线程等待的方法有很多种,下面我们就来分析一些这些方法的作用和区别.

1. public static native void yield();

1.1 源码注释翻译:

    (1). 向调度程器发起一个示意,表明当前线程乐意去放弃当前使用的处理器.调度器可以忽略这一提示.
    (2). Yield是一种启发式的尝试,用于改进线程之间的相对进展,否则会过度使用CPU.它的使用应与详细的分析和基准测试相结合,以确保它实际上达到期望的效果.
    (3). Yield方法很少有场景去是和使用.它可能对调试或测试目的很有用,它可能有助于重现因竞争条件而产生的错误.在设计并发控制结构(例如{@link java.util.concurrent.locks}包中的结构)时,它也可能很有用.

1.2 使用说明:

    yield的方法一般不怎么使用,当前线上程调用了yield方法后只是表示此乐意放弃处理器的使用权,调度器可以先去处理其他的程序.但是因为操作系统的调度室不确定的,并且线程是有优先级的,有可能会A线程调用完yield()以后,等会A线程还是会被执行. 一般用于调试程序和多线程之间调用的问题.

2. public final void join() throws InterruptedException

2.1 源码注释:

    (1). 等待这个线程死亡.
    (2). 调用此方法的行为与调用完全相同
源码:

 public final void join() throws InterruptedException {
        join(0);
    }
public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

可以看出join()调用的是join(long millis),join(0)表示永远等待,直到该线程结束.join(long millis)的判断条件是该线程是否存活.存活则调用wait方法.(wait是object类的方法)

2.2 实践例子:

public class JoinTest {

    public static void main(String[] args) throws InterruptedException {
        Thread a = new Thread(
                ()->{
                    System.out.println(Thread.currentThread().getName() + "启动");
                    System.out.println(Thread.currentThread().getName() + "结束");
                }
        );

        Thread b = new Thread(
                ()->{
                    System.out.println(Thread.currentThread().getName() + "启动");
                    try {
                        System.out.println(Thread.currentThread().getName() + "sleep 3 秒");
                        Thread.currentThread().sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "结束");
                }
        );
        b.start();
        // b.join();
        a.start();
    }
} 

这个程序当b没有join时,b肯定是后执行完毕,因为b休眠了2秒.

输出结果:
这里写图片描述
如果加上了join,则main的线程会等待b执行完毕以后,在继续往下执行a.所以输出结果是:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/sc9018181134/article/details/82289605