并发编程领域经典面试题:请使用java代码来实现“生产者消费者模式
前提: BlockingQueue(阻塞队列)是java中常见的容器,在多线程编程中被广泛使用。 当队列容器已满时生产者线程被阻塞,直到队列未满后才可以继续put; 当队列容器为空时,消费者线程被阻塞,直至队列非空时才可以继续take
@Data
public class KouZhao {
private String id;
private String type;
public KouZhao(String id, String type) {
this.id = id;
this.type = type;
}
}
public class Producer implements Runnable {
private final BlockingQueue<KouZhao> blockingQueue;
public Producer(BlockingQueue<KouZhao> blockingQueue) {
this.blockingQueue = blockingQueue;
} @
Override
public void run() {
while (true) {
try {
Thread.sleep(200);
if (blockingQueue.remainingCapacity() > 0) {
KouZhao kouZhao = new KouZhao(UUID.randomUUID().toString(),
"N95");
blockingQueue.add(kouZhao);
System.out.println("我在生产口罩,当前库存是:" +
blockingQueue.size());
} else {
System.out.println("我的仓库已经堆满了" + blockingQueue.size()
+ "个口罩,快来买口罩啊!");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Consumer implements Runnable {
private final BlockingQueue<KouZhao> blockingQueue;
public Consumer(BlockingQueue<KouZhao> blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);
long startTime = System.currentTimeMillis();
KouZhao kouZhao = blockingQueue.take();
long endTime = System.currentTimeMillis();
System.out.println("我消费了口罩:" + kouZhao + ", 等到货时我阻塞了"
+ (endTime - startTime) + "ms");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class App {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<KouZhao> queue = new ArrayBlockingQueue<>(20);
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue);
new Thread(producer).start();
Thread.sleep(20000);
new Thread(consumer).start();
}
}
JMS经典模式详解
JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间 件(MOM,Message oriented Middleware)的API,用于在两个应用程序之间,或分布式系统中发送 消息,进行异步通信。与具体平台无关的API
JMS消息
消息是JMS中的一种类型对象,由两部分组成:报文头和消息主体。 报文头包括消息头字段和消息头属性。字段是JMS协议规定的字段,属性可以由用户按需添加。 JMS报文头全部字段
字段名称 | 含义 |
---|
JMSDestination | JMSDestination 字段包含了消息要发送到的目的地 | JMSDeliveryMode | JMSDeliveryMode 字段包含了消息在发送的时候指定的投递模式 | JMSMessageID | 该字段包含了服务器发送的每个消息的唯一标识。 | JMSTimestamp | 该字段包含了消息封装完成要发往服务器的时间。不是真正向服务器发送的时间,因为真正的发送时间,可能会由于事务或客户端消息排队而延后 | JMSCorrelationID | 客户端使用该字段的值与另一条消息关联。一个典型的场景是使用该字段将响应消息与请求消息关联。JMSCorrelationID可以包含如下值: - 服务器规定的消息ID - 应用指定的字符串 - 服务器原生的byte[]值 | JMSReplyTo | 该字段包含了在客户端发送消息的时候指定的Destination。即对该消息的响应应该发送到该字段指定的Destination。设置了该字段值的消息一般期望收到一个响应 | JMSRedelivered | 如果这个字段是true,则告知消费者应用这条消息已经发送过了,消费端应用应该小心别重复处理了 | JMSType | 消息发送的时候用于标识该消息的类型。具体有哪些类型,JMS实现厂商决定 | JMSExpiration | 消息发送的时候用于标识该消息的类型。具体有哪些类型,由JMS实现厂商决定 | JMSPriority | JMS定义了一个十级优先级值,最低优先级为0,最高优先级为9。 此外, | 客户端应将优先级0-4视为正常优先级,将优先级5-9视为快速优先级。JMS不需要服务器严格执行消息的优先级排序; 但是,它应尽力在普通消息之前传递加急消息 | |
消息主体则携带着应用程序的数据或有效负载 根据有效负载的类型来划分,可以将消息分为几种类型
- 简单文本(TextMessage)
- 可序列化的对象(ObjectMessage)
- 属性集合(MapMessage)
- 字节流(BytesMessage)
- 原始值流(StreamMessage)
- 无有效负载的消息(Message)
|