JUC---join() 方法和 调用yield() ,sleep(), wait(), notify() 对锁有何影响

本文详细介绍了Java中线程的调度方式,包括join()方法的使用,使线程按序执行,以及yield(), sleep(), wait(), notify()等方法对锁的影响。通过实例代码解释了如何控制线程的执行顺序,并探讨了这些方法在锁持有情况下的行为差异。
1. join() 方法

join() 方法可以理解为一种插队现象。即线程A执行了线程B的join方法,线程A 必须等待线程B执行完成以后,才能继续往下执行。
业务需求:我们现在new出10个线程,让主线程插队,最先开始执行。剩下的线程也依次按序号插队执行。

代码:
JumpQueue()的参数是传入插队的线程,那么0号线程执行main.join(), 1号线程执行0.join(), 依次类推,所以最先执行完的是main线程。然后依次是0,1,2…9

package join的用法;

public class UseJoin {

    static class JumpQueue implements Runnable{
        private Thread thread;  //用来插队的线程

        public JumpQueue(Thread thread) {
            this.thread = thread;
        }

        @Override
        public void run() {
            try{
            	//插队执行
                thread.join();
            }catch (Exception e){
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" terminate.");
        }
    }

	//让线程依次插队执行
    public static void main(String[] args) throws InterruptedException {
        Thread previous = Thread.currentThread(); //现在是主线程
        for (int i = 0; i < 10; i++) {
            Thread thread =
                    new Thread(new JumpQueue(previous), String.valueOf(i));
            System.out.println(previous.getName()+" jump a queue the thread:"
                                +thread.getName());
            thread.start();
            previous = thread;
        }
        Thread.sleep(2000);  //让主线程休眠2s
        System.out.println(Thread.currentThread().getName()+" terminate");

    }
}

在这里插入图片描述

2.调用yield() ,sleep(), wait(), notify() 对锁有何影响

在这里插入图片描述

  • 线程在执行sleep() 方法之后,是不会释放锁的,但它在指定的睡眠的时间内会进入阻塞状态,不会被CPU所调度。(不会释放锁意味着如果有 synchronized 同步块,其他线程仍然不能访问共享数据。)
  • 线程在执行yield()方法之后,也是不会释放锁的,但它与sleep()不同,它不会进入阻塞状态,而是进入就绪状态。在下一个时间片轮转调度的情况下,CPU仍然可以调用到该方法。
  • 线程在调用wait()方法之前必须持有锁,不然会抛出异常。当调用wait()方法后,会释放锁,直到有人调用了notify()或者notifyAll()的情况下它才可能重新持有锁。(除了使用 notify() 和 notifyAll() 方法外,还可以使用带毫秒参数的 wait(long timeout) 方法,效果是在延迟 timeout 毫秒后,可以重新持有锁。还有一点需要注意的是,即使timeout时间没走完,它仍然可以被notify()或notifyAll()方法唤醒)
  • 线程在调用notify()或notifyAll() 方法之前,必须持有锁,不然也会抛出异常。但该方法调用之后本身是不会释放锁的,但因为调用方法都位于同步代码块中(Synchronized),所以执行完完整的方法自然会释放锁,所以在书写业务代码的时候,一般建议把notify()或者notifyAll() 放在同步代码块的最后执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值