在Java中,线程的暂停与唤醒是线程同步和通信的重要组成部分。Thread.sleep()方法用于暂停当前线程,而wait()、notify()和notifyAll()方法是对象级别的线程通信机制。下面将详细解释这些方法的用法及它们之间的区别。
Thread.sleep()
Thread.sleep()方法是Thread类的一部分,用于暂停当前线程的执行。它接受一个long类型的参数,表示暂停的毫秒数。如果参数为0,则当前线程将不暂停,但可能会因为其他原因(如I/O操作)被阻塞。
public class SleepExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
try {
System.out.println("Thread is sleeping...");
Thread.sleep(2000); // 暂停2秒
System.out.println("Thread is awake...");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
}
}
在这个例子中,线程将在打印“Thread is sleeping…”后暂停2秒,然后继续执行并打印“Thread is awake…”。
wait(), notify(), notifyAll()
wait()、notify()和notifyAll()方法是Object类的一部分,用于线程间的通信。它们必须在同步方法或同步块中使用。
wait()
wait()方法使当前线程等待,直到另一个线程调用该对象的notify()或notifyAll()方法。调用wait()方法后,当前线程会释放对象锁,进入等待状态。
public class WaitExample {
public static void main(String[] args) {
Object lock = new Object();
Thread producer = new Thread(() -> {
synchronized (lock) {
System.out.println("Producer is producing...");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Producer is notified and continues...");
}
});
Thread consumer = new Thread(() -> {
synchronized (lock) {
System.out.println("Consumer is consuming...");
lock.notify();
System.out.println("Consumer has notified the producer...");
}
});
producer.start();
consumer.start();
}
}
在这个例子中,生产者线程在打印“Producer is producing…”后调用wait()方法,进入等待状态。消费者线程在打印“Consumer is consuming…”后调用notify()方法,唤醒生产者线程。
notify()
notify()方法唤醒一个正在等待该对象监视器锁的线程。如果有多个线程正在等待,则任意选择一个线程唤醒。
// 上面WaitExample中的消费者线程的notify()调用
notifyAll()
notifyAll()方法唤醒所有正在等待该对象监视器锁的线程。
public class NotifyAllExample {
public static void main(String[] args) {
Object lock = new Object();
Thread producer = new Thread(() -> {
synchronized (lock) {
System.out.println("Producer is producing...");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Producer is notified and continues...");
}
});
Thread consumer = new Thread(() -> {
synchronized (lock) {
System.out.println("Consumer is consuming...");
lock.notifyAll();
System.out.println("Consumer has notified all...");
}
});
producer.start();
consumer.start();
}
}
在这个例子中,消费者线程在打印“Consumer is consuming…”后调用notifyAll()方法,唤醒所有等待的线程。
区别
- 使用范围:
Thread.sleep()是线程方法,而wait()、notify()和notifyAll()是对象方法。 - 阻塞对象:
Thread.sleep()不会释放锁,而wait()会释放锁,让其他线程可以访问该对象。 - 唤醒线程:
Thread.sleep()不会唤醒任何线程,而notify()唤醒一个线程,notifyAll()唤醒所有线程。 - 异常处理:
Thread.sleep()抛出InterruptedException,而wait()、notify()和notifyAll()不会抛出这个异常。
通过以上内容,我们可以更好地理解Java中线程暂停与唤醒的用法及区别。在实际开发中,正确使用这些方法可以有效地实现线程同步和通信。
