前言: 在本Java教程中,IT培训网小编将通过相同的生产者/消费者概念来解释BlockingQueue in Java. Java中阻塞队列的优点是什么
在本Java教程中,IT培训网小编将通过相同的生产者/消费者概念来解释BlockingQueue in Java.
Ajava.util.Queue 支持在检索元素时等待队列变为非空,并在存储元素时等待队列中的空间变为可用的操作。
我们需要创建四个 Java 类:
CrunchifyMessage.java 放置和获取消息
CrunchifyBlockingProducer.java将消息放入队列
CrunchifyBlockingConsumer.java 从队列中获取消息
CrunchifyBlockingMain.java 开始测试
BlockingQueue 实现是thread-safe. 所有排队方法本质上都是原子的并且使用内部锁。
让我们开始在 Java 中实现线程安全的 BlockingQueue
第1步
创建类 CrunchifyMessage.java。这是简单的Java 对象。
package com.crunchify.example;
/**
* @author Crunchify.com
* simple Message class to put and get message into queue
*/
public class CrunchifyMessage {
private String crunchifyMsg;
public CrunchifyMessage(String string) {
this.crunchifyMsg = string;
}
public String getMsg() {
return crunchifyMsg;
}
}
第2步
CrunchifyBlockingProducer.java 创建创建简单味精并将其放入队列的生产者 。
package com.crunchify.example;
import java.util.concurrent.BlockingQueue;
/**
* @author Crunchify.com
*
*/
public class CrunchifyBlockingProducer implements Runnable {
private BlockingQueue<CrunchifyMessage> crunchQueue;
public CrunchifyBlockingProducer(BlockingQueue<CrunchifyMessage> queue) {
this.crunchQueue = queue;
}
@Override
public void run() {
// producing CrunchifyMessage messages
for (int i = 1; i <= 5; i++) {
CrunchifyMessage msg = new CrunchifyMessage("i'm msg " + i);
try {
Thread.sleep(10);
crunchQueue.put(msg);
System.out.println("CrunchifyBlockingProducer: Message - " + msg.getMsg() + " produced.");
} catch (Exception e) {
System.out.println("Exception:" + e);
}
}
// adding exit message
CrunchifyMessage msg = new CrunchifyMessage("All done from Producer side. Produced 50 CrunchifyMessages");
try {
crunchQueue.put(msg);
System.out.println("CrunchifyBlockingProducer: Exit Message - " + msg.getMsg());
} catch (Exception e) {
System.out.println("Exception:" + e);
}
}
}
第3步
创建 CrunchifyBlockingConsumer.java 从队列中消费消息的类。
package com.crunchify.example;
import java.util.concurrent.BlockingQueue;
/**
* @author Crunchify.com
*
*/
public class CrunchifyBlockingConsumer implements Runnable {
private BlockingQueue<CrunchifyMessage> queue;
public CrunchifyBlockingConsumer(BlockingQueue<CrunchifyMessage> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
CrunchifyMessage msg;
// consuming messages until exit message is received
while ((msg = queue.take()).getMsg() != "exit") {
Thread.sleep(10);
System.out.println("CrunchifyBlockingConsumer: Message - " + msg.getMsg() + " consumed.");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
第4步
创建 CrunchifyBlockingMain.java 运行 BlockingQueue测试的简单方法。运行这个程序来检查 BlockingQueue 的行为。
package com.crunchify.example;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @author Crunchify.com
*
*/
public class CrunchifyBlockingMain {
public static void main(String[] args) {
// Creating BlockingQueue of size 10
// BlockingQueue supports operations that wait for the queue to become non-empty when retrieving an element, and
// wait for space to become available in the queue when storing an element.
BlockingQueue<CrunchifyMessage> crunchQueue = new ArrayBlockingQueue<>(10);
CrunchifyBlockingProducer crunchProducer = new CrunchifyBlockingProducer(crunchQueue);
CrunchifyBlockingConsumer crunchConsumer = new CrunchifyBlockingConsumer(crunchQueue);
// starting producer to produce messages in queue
new Thread(crunchProducer).start();
// starting consumer to consume messages from queue
new Thread(crunchConsumer).start();
System.out.println("Let's get started. Producer / Consumer Test Started.\n");
}
}
BlockingQueue不接受空元素。在尝试添加、放置或提供null时,实现会抛出NullPointerException。
null用作标记值以指示轮询操作失败。
结果:
Let's get started. Producer / Consumer Test Started.
CrunchifyBlockingProducer: Message - i'm msg 1 produced.
CrunchifyBlockingProducer: Message - i'm msg 2 produced.
CrunchifyBlockingConsumer: Message - i'm msg 1 consumed.
CrunchifyBlockingConsumer: Message - i'm msg 2 consumed.
CrunchifyBlockingProducer: Message - i'm msg 3 produced.
CrunchifyBlockingConsumer: Message - i'm msg 3 consumed.
CrunchifyBlockingProducer: Message - i'm msg 4 produced.
CrunchifyBlockingConsumer: Message - i'm msg 4 consumed.
CrunchifyBlockingProducer: Message - i'm msg 5 produced.
CrunchifyBlockingProducer: Exit Message - All done from Producer side. Produced 50 CrunchifyMessages
CrunchifyBlockingConsumer: Message - i'm msg 5 consumed.
CrunchifyBlockingConsumer: Message - All done from Producer side. Produced 50 CrunchifyMessages consumed.
当您想限制某种传入请求时,您应该使用相同的
生产者可以通过无限队列远远领先于消费者。如果消费者没有赶上生产者,那么它可能会导致 OutOfMemoryError. 在这种情况下,最好向潜在的生产者发出队列已满的信号,并在失败后迅速放弃。
换句话说:生产者自然受到限制。
阻塞队列通常用于并发应用程序
它提供了正确的、线程安全的实现
内存消耗也应该受到限制
Java队列文章出自:http://qh.itpxw.cn/peixun/software/2022123851.html
文章标题:Java线程安全的阻塞队列
免责声明:本站文章均由入驻起航学习网的会员所发或者网络转载,所述观点仅代表作者本人,不代表起航学习网立场。如有侵权或者其他问题,请联系举报,必删。侵权投诉
IT培训网 访问该机构站点 报名留言 加为好友 用户等级:注册会员
用户级别:10
机构名称:IT培训网
联 系 人:罗老师
联系电话:13783581536
联系手机:13783581536
在线客服:
在 线 QQ:
电子邮件:
网站域名:http://www.itpxw.cn
注册时间:2016-07-18 11:07
最后登录:2024-02-20 13:02
Java定义方法的格式是什么?IT培训网小编来告诉大家。所谓方法...
大家在Java教程中会学到关于Java消息推送的知识,那么,Java消息...
常用的Java日期格式转换有哪些?IT培训网小编来告诉大家。 1...
Java创建对象数组的方法是什么?IT培训网小编来告诉大家。Ja...