LinkedBlockingQueue 在 Java 中的 take() 方法及其示例
LinkedBlockingQueue 是 Java 中的一个线程安全的队列实现,它是基于链表的实现,对于并发访问的情况,它的性能表现优异,常被用作生产者消费者模型中的消息队列。
take() 方法概述
在 LinkedBlockingQueue 中,常用的方法之一就是 take() 方法,它用于取出队列中的元素,如果队列为空,则线程会一直阻塞等待元素的到来。
public E take() throws InterruptedException {}
take() 方法返回队首的元素,如果队列为空,则线程会一直阻塞等待,直到有元素被放入队列。在等待期间,线程会处于阻塞状态。
此方法类似于 poll() 方法,但是,如果队列为空,poll() 方法会返回 null,但是 take() 方法会一直等待元素的到来。
示例代码
对于 LinkedBlockingQueue 的 take() 方法,下面我们来看一个简单的示例代码。
首先,创建一个 LinkedBlockingQueue 实例:
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(5);
用于放入队列的生产者线程,代码如下:
Thread producer = new Thread(() -> {
try {
for (int i = 1; i <= 10; i++) {
String msg = "message_" + i;
queue.put(msg);
System.out.println(Thread.currentThread().getId() + ": " + msg + " put into queue.");
Thread.sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
这里用了一个简单的循环,向队列中放入 10 个元素,并且打印出每个元素的线程 ID 和元素内容,并且每放完一个元素,线程就休眠 500 毫秒,模拟业务操作。
用于消费队列中元素的消费者线程,代码如下:
Thread consumer = new Thread(() -> {
try {
for (int i = 1; i <= 10; i++) {
String msg = queue.take();
System.out.println(Thread.currentThread().getId() + ": " + msg + " is taken from queue.");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
这里也用了一个简单的循环,用于从队列中取出 10 个元素,并且打印出每个元素的线程 ID 和元素内容,并且每取完一个元素,线程就休眠 1 秒,模拟业务操作。
最后启动线程并等待线程结束,代码如下:
producer.start();
consumer.start();
producer.join();
consumer.join();
这里,首先启动生产者和消费者线程,然后等待两个线程都结束后再结束主线程。
完整代码如下:
import java.util.concurrent.LinkedBlockingQueue;
public class LinkedBlockingQueueExample {
public static void main(String[] args) throws InterruptedException {
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(5);
Thread producer = new Thread(() -> {
try {
for (int i = 1; i <= 10; i++) {
String msg = "message_" + i;
queue.put(msg);
System.out.println(Thread.currentThread().getId() + ": " + msg + " put into queue.");
Thread.sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread consumer = new Thread(() -> {
try {
for (int i = 1; i <= 10; i++) {
String msg = queue.take();
System.out.println(Thread.currentThread().getId() + ": " + msg + " is taken from queue.");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
producer.start();
consumer.start();
producer.join();
consumer.join();
}
}
结论
本文简要介绍了 LinkedBlockingQueue 在Java 中的 take() 方法,该方法用于从队列中取出元素,如果队列为空,则会阻塞等待,直到元素被放入队列中。
示例代码展示了如何使用生产者消费者模型和 LinkedBlockingQueue 的 take() 方法,构建一个简单的消息队列系统。
在使用 take() 方法时要注意,如果队列为空,则会一直阻塞等待元素的到来,这可能会导致线程一直被占用,所以需要根据实际需求合理使用该方法。