多线程编程是现代软件开发中的常见需求,而线程的控制和协作则是其中的关键挑战之一。在Java中,有两种主要的方法可以用来让线程暂停执行:Thread
类的sleep()
方法和对象的wait()
方法。本文将深入研究这两种方法,分析它们的区别,以及在不同情况下何时使用哪种方式来控制线程的执行。
Thread.sleep() 方法
Thread.sleep()
方法是Thread
类的静态方法,用于让当前线程休眠一段指定的时间。该方法接受一个毫秒数作为参数,表示线程将休眠的时间长度。在休眠期间,线程不会释放它所持有的任何锁,因此其他线程无法获得这些锁。
以下是一个简单的示例,演示了如何使用Thread.sleep()
方法:
public class SleepExample {
public static void main(String[] args) throws InterruptedException {
System.out.println("Start of the program");
Thread.sleep(2000); // 线程休眠2秒
System.out.println("End of the program");
}
}
在上面的示例中,主线程休眠了2秒后继续执行。
对象的 wait() 方法
wait()
方法是Object
类的方法,用于让当前线程等待,直到其他线程调用相同对象的notify()
或notifyAll()
方法来唤醒它。wait()
方法通常与synchronized
关键字一起使用,以确保线程在等待期间释放锁,从而允许其他线程访问共享资源。
以下是一个示例,演示了如何使用wait()
和notify()
方法来实现线程的协作:
public class WaitNotifyExample {
public static void main(String[] args) {
final Object lock = new Object();
Thread thread1 = new Thread(new Runnable() {
public void run() {
synchronized (lock) {
System.out.println("Thread 1: Waiting...");
try {
lock.wait(); // 等待被唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1: Resumed.");
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
synchronized (lock) {
System.out.println("Thread 2: Waking up Thread 1...");
lock.notify(); // 唤醒等待的线程
}
}
});
thread1.start();
thread2.start();
}
}
在上面的示例中,thread1
等待被thread2
唤醒,然后继续执行。
Thread.sleep() vs. 对象的 wait():区别对比
现在让我们比较一下Thread.sleep()
方法和对象的wait()
方法的区别。
1. 暂停的对象不同:
Thread.sleep()
方法是Thread
类的方法,用于暂停当前线程的执行。wait()
方法是Object
类的方法,用于暂停当前线程,并释放锁,使其他线程可以访问相同对象的临界区。
2. 使用场景不同:
Thread.sleep()
通常用于暂停当前线程的执行,以模拟时间的流逝或实现线程的定时等待。wait()
通常用于线程之间的协作,允许一个线程等待另一个线程的通知或信号。
3. 锁的释放情况不同:
Thread.sleep()
不会释放任何锁,线程休眠期间其他线程无法获得锁。wait()
方法会释放对象的锁,让其他线程有机会进入对象的临界区。
4. 唤醒方式不同:
Thread.sleep()
不需要其他线程来唤醒,线程会在休眠时间结束后自动恢复执行。wait()
需要其他线程调用相同对象的notify()
或notifyAll()
方法来唤醒等待的线程。
5. 异常处理不同:
Thread.sleep()
可以抛出InterruptedException
异常,需要进行异常处理。wait()
方法也可以抛出InterruptedException
异常,需要进行异常处理。
示例代码续
让我们继续之前的示例,演示如何使用wait()
和notify()
来实现线程的协作。
public class WaitNotifyExample {
public static void main(String[] args) {
final Object lock = new Object();
Thread thread1 = new Thread(new Runnable() {
public void run() {
synchronized (lock) {
System.out.println("Thread 1: Waiting...");
try {
lock.wait(); // 等待被唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1: Resumed.");
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
synchronized (lock) {
try {
Thread.sleep(2000); // 等待2秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 2: Waking up Thread 1...");
lock.notify(); // 唤醒等待的线程
}
}
});
thread1.start();
thread2.start();
}
}
在这个续篇示例中,thread1
使用wait()
方法等待被thread2
唤醒,而thread2
使用Thread.sleep()
方法休眠2秒后唤醒thread1
。这个示例演示了Thread.sleep()
和wait()
在协作中的不同用法。
结语
Thread.sleep()
方法和对象的wait()
方法都可以让线程暂停执行,但它们有不同的用途和行为。选择哪种方式取决于你的需求和场景。希望本文能够帮助你更好地理解这两种方法的区别,以及如何在多线程编程中使用它们。
我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表