Thead wait notify notifyAll join yeid sleep

thread的wait notifyAll notify 只能在同步代码中调用。
wait 释放当前的锁,并进入等待状态,如果没有别的线程调用notifyall 或者notify() 则会一直处于等待状态:

public class SynDemo {

    private Object lock;

    public SynDemo(Object lock) {
        this.lock = lock;
    }

    public void test1(){
        synchronized (lock){
            System.out.println("test1 is running1");
            try {
                Thread.sleep(2000);
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("test1 is running2");

        }
    }

    public void test2() {
        synchronized (lock){
            System.out.println("test2 is running1");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.notify();
            System.out.println("test2 is running2");
        }
    }

}

调用:

	Object lock = new Object();

		Thread third = new Thread(()->{
			SynDemo demo =  new SynDemo(lock);
			demo.test1();

		});
		third.start();
		Thread five = new Thread(()->{
			SynDemo demo =  new SynDemo(lock);
			demo.test2();

		});
		five.start();
		打印结果:
		test1 is running1
        test2 is running1
        test2 is running2
        test1 is running2

线程third 中调用test1方法,首先获得同步锁,然后休眠了2秒,这个时候还占用着同步锁,之后调用wait,释放同步锁,线程five中的test2获得同步锁,调用lock.notify();唤醒线程third,但是five并没有释放锁,而是等在执行完之后,third才获得锁。由此可见调用了notify之后,并不会释放锁,只是唤醒被wait的线程而已。
notify()和notifyAll的区别是,notify只会随机的唤醒一个线程,notifyAll唤醒全部wait的线程,所以在实际使用的时候尽量使用notifyAll。

Java线程中的join的意义在于等我执行完你在执行。

Thread first = new Thread(() -> {

            System.out.println("first start running ");
             Thread second = new Thread(() -> {
				System.out.println("Second is running");
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
            });

			second.start();
            try {
				second.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("first end running");
        });
		first.start();
        结果:
        first start running 
        Second is running
        first end running

意思说first线程执行到second.join()之后,等到second执行完了之后在继续执行

看join的源码很有意思,并且还有点绕。

   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(0)这个方法,并且这个join(0)这个方式是synchronized的,也就是同步的。需要注意的是这个join方法是由first来调用的。 继续往下传进来的参数是0,所以会进入一个下面这个循环

while (isAlive()) {
      wait(0);
 }

如果是true的话,表示的是当前线程进入wait,也就是释放锁,让出CPU,所以当前的线程就是不会往下执行了。 而这个isAlive()判断是second的线程有没有执行完,如果执行完了也就返回false了就退出循环,然后first开始继续执行。

thead.yeild()方法会让线程暂时的释放CPU资源。然后所有的线程在同时竞争CPU资源,当然调用thread.yeild()也会重新参与竞争CPU资源。所以他的意思是让资源重新调度一次。 但是如果有同步锁,yeild()方法不会释放同步锁,所以如果有多个线程在等待同步锁,yeild方法不会释放同步锁,等待同步锁线程还是不会执行,那么还是当前线程得到CPU执行。

同样的还有sleep方法,sleep方法既不会释放CPU资源也不会释放同步锁。

欢迎关注我的公众号: manong_xiaodong或扫一扫下面的二维, 有大数据资料赠送哟,因为我最近也在学习大数据!欢迎一起学习!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟红尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值