侧边栏壁纸
博主头像
翻斗

开始一件事最好是昨天,其次是现在

  • 累计撰写 44 篇文章
  • 累计创建 42 个标签
  • 累计收到 3 条评论

wait vs sleep

翻斗
2020-04-12 / 0 评论 / 0 点赞 / 633 阅读 / 1,782 字

Baeldung 翻译系列之Java并发基础:

Java中的concurrent包
Java中的Synchronized关键字
Future介绍
ThreadLocal介绍
Java线程的生命周期
如何杀掉一个Java线程
Java中的线程池介绍
实现Runnable接口还是继承Thread类
Java中的wait和notify方法
Runnable vs Callable
wait和sleep的区别
Thread.join方法介绍
Java中使用锁对象
ThreadPoolTaskExecutor中的corePoolSize和maxPoolSize
Java中的异步编程

1. 概览

在这篇简短的文章中,我们将会比对Java标准库中的sleep()wait()方法,理解他们之间的相似处和不同点。

2. wait和sleep的一般区别

简单来说,wait()是一个实例方法,用于线程同步。

它可以在任何对象上调用,因为它直接定义在java.lang.Object上,但它只能从同步块中调用。它释放了对象上的锁,以便另一个线程可以跳入并获取锁。

另一方面,Thread.sleep()是一个静态方法,可以从任何上下文中调用Thread.sleep()暂停当前线程并且不释放任何锁。

下面是这两个核心API的一个非常简单的初步演示:

private static Object LOCK = new Object();

private static void sleepWaitExamples() 
  throws InterruptedException {
 
    Thread.sleep(1000);
    System.out.println(
      "Thread '" + Thread.currentThread().getName() +
      "' is woken after sleeping for 1 second");
 
    synchronized (LOCK) {
        LOCK.wait(1000);
        System.out.println("Object '" + LOCK + "' is woken after" +
          " waiting for 1 second");
    }
}

运行这个例子将产生以下输出:

线程main在睡眠1秒后被唤醒
对象java.lang.Object@31befd9f在等待1秒后被唤醒

3. 唤醒wait和sleep

当我们使用sleep()方法时,线程会在指定的时间间隔后启动,除非它被中断。

对于wait(),唤醒过程稍微复杂一些。我们可以通过在被等待的监视器上调用notify()notifyAll()方法来唤醒线程。

当你想唤醒所有处于等待状态的线程时,应该使用notifyAll()而不是notify()。和wait()方法本身一样,notify()notifyAll()必须在同步上下文中调用。

例如,这是你可以等待的方式:

synchronized (b) {
    while (b.sum == 0) {
        System.out.println("Waiting for ThreadB to complete...");
        b.wait();
    }

    System.out.println("ThreadB has completed. " + 
      "Sum from that thread is: " + b.sum);
}

然后,这是另一个线程如何通过在监视器上调用notify()来唤醒等待的线程:

int sum;
 
@Override 
public void run() {
    synchronized (this) {
        int i = 0;
        while (i < 100000) {
            sum += i;
            i++; 
        }
        notify(); 
    } 
}

运行这个例子将产生以下输出:

Waiting for ThreadB to complete…
ThreadB has completed. Sum from that thread is: 704982704

4. 总结

这是Java中waitsleep语义的快速入门。

总的来说,我们应该使用sleep()来控制一个线程的执行时间,使用wait()进行多线程同步。当然,在理解基础知识之后,还有很多可以探索的内容。

和往常一样,你可以在GitHub 或者 Gitee 上查看本文中提供的示例。

0

评论区