sleep()、wait()和join()的对比

sleep()

public class Demo2 {
    private static final String lock = new String("lock");

    public static void main(String[] args) {
        myThread();
        myThread();
    }

    private static void myThread() {
        new Thread(() -> {
            System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "正在运行");
            synchronized (lock) {
                try {
                    System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "获取到锁");
                    System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "sleep");
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "运行结束");
            }
        }).start();
    }
}

执行结果:

1655345999323Thread-0正在运行
1655345999323Thread-1正在运行
1655345999331Thread-0获取到锁
1655345999331Thread-0sleep
1655346009336Thread-0运行结束
1655346009338Thread-1获取到锁
1655346009338Thread-1sleep
1655346019343Thread-1运行结束

总结:

  1. sleep()是Thread的静态方法;
  2. 从执行结果看,在线程0调用 sleep() 后,线程1并没有获取到锁。而是等线程0运行结束后,才获取到锁。说明线程调用 sleep() 后,是不会释放锁的。

wait()

指定等待的时间,到期后自动被唤醒

package com.learn.blog.demo;

public class Demo3 {
    private static final String lock = new String("lock");

    public static void main(String[] args) {
        myThread();
        myThread();
    }

    private static void myThread() {
        new Thread(() -> {
            System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "正在运行");
            synchronized (lock) {
                try {
                    System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "获取到锁");
                    System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "wait");
                    lock.wait(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "运行结束");
            }
        }).start();
    }
}

执行结果:

1655346407235Thread-1正在运行
1655346407235Thread-0正在运行
1655346407243Thread-1获取到锁
1655346407243Thread-1wait
1655346407243Thread-0获取到锁
1655346407244Thread-0wait
1655346408249Thread-1运行结束
1655346408249Thread-0运行结束

总结:

  1. wait()是Ojbect的静态方法;
  2. wait()可以指定等待时长,到期后自动被唤醒;
  3. 从执行结果看,在线程1调用 wait() 后,线程0马上就获取到锁,并不需要等到线程1执行结束。说明线程调用 wait() 后,会释放锁。

不指定等待时长,需要手动notify/notifyAll唤醒

package com.learn.blog.demo;

public class Demo4 {
    private static final String lock = new String("lock");

    public static void main(String[] args) {
        myThread();
        myThread();
    }

    private static void myThread() {
        new Thread(() -> {
            System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "正在运行");
            synchronized (lock) {
                try {
                    lock.notify();
                    System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "获取到锁");
                    System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "wait");
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "运行结束");
            }
        }).start();
    }
}

执行结果:

1655347146777Thread-0正在运行
1655347146777Thread-1正在运行
1655347146785Thread-0获取到锁
1655347146785Thread-0wait
1655347146785Thread-1获取到锁
1655347146785Thread-1wait
1655347146785Thread-0运行结束

总结:

从执行结果看,在线程0调用 wait 后,线程1获取到锁,调用notify唤醒了线程0,然后自己进入wait。此时,线程0获取到锁,线程0执行结束。线程1依然处于等待状态,没有线程唤醒它,所以线程1一直没有执行结束。


join()

package com.learn.blog.demo;

public class Demo5 {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("主线程执行开始");
        Thread thread = new Thread(() -> {
            System.out.println("join线程执行开始");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("join线程执行结束");
        });
        thread.start();
        thread.join();
        System.out.println("主线程执行结束");
    }
}

执行结果:

主线程执行开始
join线程执行开始
join线程执行结束
主线程执行结束

总结:

join()执行后线程进入阻塞状态,例如线程A中调用线程B的join(),那么线程A会进入到阻塞队列,直到线程B结束。


sleep、wait和join的总结

sleep()和wait()对比

  1. sleep()是Thread的静态本地方法,wait()是Object的静态本地方法
  2. sleep()不会释放lock,wait()会释放lock
  3. sleep()不需要被唤醒,wait()需要(不指定等待时长的情况)

join()执行后线程进入阻塞状态,例如线程A中调用线程B的join(),那么线程A会进入到阻塞队列,直到线程B结束

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值