java并发系列-Java中wait()和sleep()的区别

1 概述

这篇文章会给我们介绍一下core java中标准的sleep()wait()方法,并理解它们的异同之处。

2 Wait和Sleep的区别

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

它定义在java.lang.Object中,可以被任何对象调用,不过只能在同步代码块中调用。它会在对象上释放一个锁,线程进来执行,需要拿到这个锁。

Thread.sleep()是一个静态方法,可以在任何上下文(context)中调用。Thread.sleep()不释放任何锁,只是暂定当前线程执行。

下面简单看看两个方法的行为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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");
}
}

下面是执行输入:

1
2
Thread ‘main' is woken after sleeping for 1 second
Object ‘java.lang.Object@31befd9f' is woken after waiting for 1 second

3 Wait和Sleep后怎样继续执行程序

当执行sleep()方法时,线程会等待指定时间启动恢复,排除它被中断的情况。

对于wait(), 线程恢复过程就有一点点复杂。我们需要当进行等待的监视器(monitor)上调用notify()或者notifyAll()方法恢复线程执行。

看看下面使用wait()的例子:

1
2
3
4
5
6
7
8
9
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()来唤醒等待的线程:

1
2
3
4
5
6
7
8
9
10
11
12
13
int sum;

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

执行这个例子会输出如下结果:

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

4 总结

这篇文章简单介绍了java中waitsleep的语法。

通常,sleep()用于控制线程执行时间,wait()用于多线程同步。这只是简单的理解,其实还有很多用法可以探索。


本文为译文,作者通过翻译达到学习目的。 原文链接 | 原文源码链接 | 本站源码链接