下面我将为你详细讲解“Java多线程wait()和notify()方法详细图解”的完整攻略。
什么是wait()和notify()方法?
Java多线程的wait()和notify()方法是多线程协作技术的核心。等待/通知机制的目的就是解决线程间协作的问题,它通常是指一个或多个线程等待另一个线程的通知而处于阻塞状态,然后另一个线程发出通知以唤醒这些等待的线程。
wait()方法和notify()方法就是一对典型的等待/通知机制方法,它们都属于Object类的方法,而且只能在同步块或同步方法中使用。在调用这两个方法时,必须首先获得对象的锁,然后才能调用wait()方法释放锁并进入等待状态,调用notify()方法通知等待状态的线程而使其重新获得锁并进入就绪状态。下面是wait()方法和notify()方法的详细说明:
-
wait()方法
wait()方法用于让当前线程处于等待状态,直到其他线程调用notify()或notifyAll()方法来唤醒它。wait()方法必须在synchronized块或synchronized方法中调用,否则会抛出IllegalMonitorStateException异常。
-
notify()方法
notify()方法用于唤醒在当前对象上等待的一个线程,如果有多个线程在等待,只会唤醒其中一个线程,并且是系统随机选择的。如果需要唤醒全部等待的线程,则需要使用notifyAll()方法。notify()方法也必须在synchronized块或synchronized方法中进行调用,否则会抛出IllegalMonitorStateException异常。
wait()和notify()方法的示例
下面我将为你提供两个示例来讲解wait()和notify()方法的使用:
示例一:生产者-消费者模式
在这个示例中,我们将使用生产者-消费者模式来演示wait()和notify()方法的使用。
class Message {
private String message;
private boolean isSet;
public synchronized void put(String message) {
if (this.isSet) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.message = message;
this.isSet = true;
notify();
}
public synchronized String get() {
if (!this.isSet) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String message = this.message;
this.isSet = false;
notify();
return message;
}
}
class Producer implements Runnable {
private Message message;
public Producer(Message message) {
this.message = message;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
this.message.put("Message-" + i);
}
}
}
class Consumer implements Runnable {
private Message message;
public Consumer(Message message) {
this.message = message;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Received Message: " + this.message.get());
}
}
}
public class WaitNotifyExample {
public static void main(String[] args) {
Message message = new Message();
Thread producerThread = new Thread(new Producer(message));
Thread consumerThread = new Thread(new Consumer(message));
producerThread.start();
consumerThread.start();
try {
producerThread.join();
consumerThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
上述示例中,我们定义了一个Message类来保存消息,并且在Message类中实现了put()方法和get()方法,put方法用于发送消息,get方法用于接收消息,并且在这两个方法中使用了wait()和notify()方法来实现线程间的协作。在程序运行时,我们启动了一个生产者线程和一个消费者线程,并且在main方法中使用join()方法来等待两个线程的结束。
示例二:简单线程池
在这个示例中,我们将使用一个简单的线程池来演示wait()和notify()方法的使用。
class SimpleThreadPool {
private final BlockingQueue<Runnable> taskQueue;
private final List<WorkerThread> workerThreads;
private volatile boolean isShutdown;
public SimpleThreadPool(int poolSize, int maxTasks) {
this.taskQueue = new ArrayBlockingQueue<>(maxTasks);
this.workerThreads = new ArrayList<>(poolSize);
this.isShutdown = false;
for (int i = 0; i < poolSize; i++) {
WorkerThread workerThread = new WorkerThread("Thread-" + i, this.taskQueue, this);
this.workerThreads.add(workerThread);
workerThread.start();
}
}
public void submit(Runnable task) throws InterruptedException {
if (this.isShutdown) {
throw new IllegalStateException("Thread pool is shut down.");
}
this.taskQueue.put(task);
}
public void shutdown() {
this.isShutdown = true;
this.workerThreads.forEach(WorkerThread::shutdown);
}
}
class WorkerThread extends Thread {
private final BlockingQueue<Runnable> taskQueue;
private final SimpleThreadPool threadPool;
private volatile boolean isShutdown;
public WorkerThread(String name, BlockingQueue<Runnable> taskQueue, SimpleThreadPool threadPool) {
super(name);
this.taskQueue = taskQueue;
this.threadPool = threadPool;
this.isShutdown = false;
}
@Override
public void run() {
while (!this.isShutdown || !this.taskQueue.isEmpty()) {
try {
Runnable task = this.taskQueue.poll(1, TimeUnit.SECONDS);
if (task != null) {
System.out.println(Thread.currentThread().getName() + ": Starting task.");
task.run();
System.out.println(Thread.currentThread().getName() + ": Task completed.");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void shutdown() {
this.isShutdown = true;
}
}
public class WaitNotifyExample {
public static void main(String[] args) throws InterruptedException {
SimpleThreadPool threadPool = new SimpleThreadPool(2, 4);
for (int i = 0; i < 6; i++) {
threadPool.submit(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": Executing task.");
});
}
Thread.sleep(5000);
threadPool.shutdown();
}
}
上述示例中,我们定义了一个SimpleThreadPool类来实现一个简单的线程池,并且使用了wait()和notify()方法来实现线程间的协作。在程序运行时,我们使用一个线程池来提交6个任务,并且在任务执行完毕后关闭线程池。在线程池中,我们启动了两个执行任务的线程,并且使用wait()方法来使线程等待任务队列中有新的任务时,notify()方法来唤醒等待线程继续执行任务。
以上就是对“Java多线程wait()和notify()方法详细图解”的完整攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程wait()和notify()方法详细图解 - Python技术站