Java线程休眠方法sleep、线程让步yield和join方法

线程休眠(sleep方法)

线程休眠:让线程暂缓执行,等到预计时间之后再恢复执行。

线程休眠会交出cpu,让cpu去执行其他任务,但是不会释放锁。
比如:当前线程sleep休眠了,但是如果此线程在休眠前持有某个对象的锁,那就算它休眠了其他线程也不能获取到这个对象的锁。

注意:调用sleep结束后线程会重新回到就绪状态,只需要等待获取cpu执行就可以。

方法:

public static native void sleep(long millis) throws InterruptedException

休眠的时间是以毫秒为单位
使用:

class MyThread implements Runnable{
    @Override
    public void run() {
        for(int i = 0; i < 5; i++){
            try {
                sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" i=" + i);
        }
    }
}

public class Test{
    public static void main(String[] args){
        MyThread myThread = new MyThread();
        new Thread(myThread).start();
        new Thread(myThread).start();
        new Thread(myThread).start();
    }
}

线程让步(yield()方法)

yield():暂停当前正在执行的线程对象,并执行其他线程。

线程让步会交出cpu权限,让cpu去执行其他的线程。和sleep方法类似,同样不会释放锁,但是yield不能控制具体交出cpu的时间,并且,yield方法只能让拥有相同优先级的线程有获取cpu执行的机会。

注意:调用yield结束后线程会重新回到就绪状态,只需要等待获取cpu执行就可以。

使用:

class MyThread implements Runnable{
    @Override
    public void run() {
        for(int i = 0; i < 5; i++){
            Thread.yield();
            System.out.println(Thread.currentThread().getName()+" i=" + i);
        }
    }
}

public class Test{
    public static void main(String[] args){
        MyThread myThread = new MyThread();
        new Thread(myThread).start();
        new Thread(myThread).start();
        new Thread(myThread).start();
    }
}

等待其他线程终止-join()方法

意思就是说如果在主线程中调用这个方法时会让主线程休眠,让调用该方法的线程run方法先执行完毕后再开始执行主线程。
在这里插入图片描述
join放发实际上是对wait方法的封装。

我们来看join的源码

public final void join() throws InterruptedException {
        join(0);
    }

我们可以看到join方法实际上是调用了join(0);

join(long millis)方法如下:


    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(0)调用的部分代码;如下:

if (millis == 0) {
            while (isAlive()) {//判断当前线程是否为Running状态
                wait(0);
            }

从上面可以看出如果调用此方法的线程是正在运行的线程,那么就会调用wait(0)方法,

关于wait()的源码:

    public final native void wait(long timeout) throws InterruptedException;

wait(long timeout)是一个本地方法,调用本机的原生系统函数,当Thread类被加载到JVM中的时候,它就会调用注册相应的本地方法。
wait(0)就是让其他线程一直在等待,当此线程终止时,会调用线程自身的notifyAll()方法,唤醒所有等待在该线程对象上的线程。

使用:

public class Test{
    public static void main(String[] args) throws InterruptedException {

        final Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("t1");
            }
        });
        final Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    t1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("t2");
            }
        });
        final Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    t2.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("t3");
            }
        });

        t1.start();
        t3.start();
        
        t2.start();


    }
}

运行结果:

t1
t2
t3

当t2比t3start时间迟的时候,出现下面结果

public class Test{
    public static void main(String[] args) throws InterruptedException {

        final Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("t1");
            }
        });
        final Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    t1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("t2");
            }
        });
        final Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    t2.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("t3");
            }
        });

        t1.start();
        t3.start();
        Thread.sleep(2000);//让主线程休眠2秒,那么在t3调用join时t2还不是运行状态
        t2.start();


    }
}

运行结果如下:

t1
t3
t2

这就是因为join(0)中调用了

if (millis == 0) {
            while (isAlive()) {//判断当前线程是否为Running状态
                wait(0);
            }

因为t2不处于运行状态所以不会执行wait(0),所以t3就不会等待,直接运行下一条语句。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值