等待队列和执行队列

在Java中,等待队列和执行队列是非常常见的概念。它们在多线程编程中起着重要的作用,用于协调线程的执行顺序和相互之间的通信。

等待队列

等待队列是指一个存储等待线程的数据结构,用于在特定条件满足之前暂停线程的执行。当一个线程调用某个对象的wait()方法时,它会被放入等待队列中,直到其他线程调用相同对象的notify()notifyAll()方法将其唤醒。

等待队列的主要作用是提供一种线程间通信的机制,使得线程能够等待某个条件的发生,从而避免了线程的忙等待,提高了线程的效率。

在Java中,等待队列通常与synchronized关键字一起使用,如下所示的示例代码:

public class WaitQueueExample {
    private static final Object lock = new Object();

    public static void main(String[] args) {
        Thread producerThread = new Thread(() -> {
            synchronized (lock) {
                try {
                    System.out.println("Producer is waiting...");
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Producer is resumed.");
            }
        });

        Thread consumerThread = new Thread(() -> {
            synchronized (lock) {
                System.out.println("Consumer is notifying...");
                lock.notify();
            }
        });

        producerThread.start();
        consumerThread.start();
    }
}

在上述代码中,producerThread线程调用了lock.wait()方法,将自己放入了等待队列中。而consumerThread线程调用了lock.notify()方法,唤醒了等待队列中的线程。

执行队列

执行队列是指一个存储等待执行任务的数据结构,用于按照一定的顺序和策略执行任务。通常情况下,执行队列是由线程池来管理的,它通过维护一个线程池和一个任务队列来实现任务的执行。

线程池在Java中的实现是ExecutorService接口及其实现类ThreadPoolExecutor。当一个任务被提交到线程池时,如果线程池中有空闲线程,任务就会立即被执行;如果线程池中没有空闲线程,任务则会被放入任务队列中,等待空闲线程的出现。

下面是一个使用ThreadPoolExecutor的示例代码:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorServiceExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        for (int i = 0; i < 5; i++) {
            final int taskId = i;
            executorService.submit(() -> {
                System.out.println("Task " + taskId + " is running.");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Task " + taskId + " is finished.");
            });
        }

        executorService.shutdown();
    }
}

在上述代码中,我们创建了一个固定大小为2的线程池,然后提交了5个任务。由于线程池的大小为2,所以只能同时执行两个任务,剩下的任务会被放入任务队列中,等待线程空闲。

总结

等待队列和执行队列是多线程编程中常用的概念。等待队列用于暂停线程的执行,直到某个条件满足;执行队列用于按照一定顺序和策略执行任务。通过合理地使用等待队列和执行队列,我们可以实现线程间的协作,提高多线程程序的效率和可靠性。