什么叫网站流量,建设部标准定额研究所网站,百度浏览器官网下载并安装,网页效果图制作生产者消费者
与保护性暂停中的不同#xff0c;不需要产生结果和消费结果的线程一一对应。
生产者仅负责产生结果数据#xff0c;不关心数据该如何处理#xff0c;而消费者专心处理结果数据
JDK 中各种阻塞队列#xff0c;采用的就是这种模式
代码实现#xff1a; 首先…生产者消费者
与保护性暂停中的不同不需要产生结果和消费结果的线程一一对应。
生产者仅负责产生结果数据不关心数据该如何处理而消费者专心处理结果数据
JDK 中各种阻塞队列采用的就是这种模式
代码实现 首先设计消息队列类MessageQueue需要指定容量capacity用双向链表list作为容器。 提供take方法检查list是否是空空的话就wait如果不空就打印Message并唤醒所有线程。 提供put方法检查list是否满了满了的话就wait如果不满就添加Message并唤醒所有线程。 可以看到以上的写法都是使用wait和notify的模板写法。
class MessageQueue{private LinkedListMessage list new LinkedList();private int capacity;public MessageQueue(int capacity) {this.capacity capacity;}//取public Message take(){synchronized (list){while (list.isEmpty()){try {log.debug(队列空了);list.wait();} catch (InterruptedException e) {e.printStackTrace();}}Message message list.removeFirst();log.debug(取出来了{}, message);list.notifyAll();return message;}}//存public void put(Message message){synchronized (list){while(list.size() capacity){try {log.debug(队列满了);list.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.addLast(message);log.debug(添加了{}, message);list.notifyAll();}}
} 设计Message类需要一个唯一标识id还需要一个Object类型的value值。
final class Message{private int id;private Object value;public Message(int id, Object value) {this.id id;this.value value;}public int getId() {return id;}public Object getValue() {return value;}Overridepublic String toString() {return Message{ id id , value value };}
} 完整代码
public class ProductAndConsumer {public static void main(String[] args) {MessageQueue q new MessageQueue(3);for (int i 1; i 5; i){//lambda表达式必须传final的值不能变。int id i;new Thread(()-{q.put(new Message(id, vid));}, 生产者).start();}new Thread(()-{while (true){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}Message t q.take();}}, 消费者).start();}
}/*** 消息队列类*/
Slf4j(topic c.test)
class MessageQueue{private LinkedListMessage list new LinkedList();private int capacity;public MessageQueue(int capacity) {this.capacity capacity;}//取public Message take(){synchronized (list){while (list.isEmpty()){try {log.debug(队列空了);list.wait();} catch (InterruptedException e) {e.printStackTrace();}}Message message list.removeFirst();log.debug(取出来了{}, message);list.notifyAll();return message;}}//存public void put(Message message){synchronized (list){while(list.size() capacity){try {log.debug(队列满了);list.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.addLast(message);log.debug(添加了{}, message);list.notifyAll();}}
}/*** Message对象只有get方法并且final不可继承也不会被子类重写方法很安全。*/
final class Message{private int id;private Object value;public Message(int id, Object value) {this.id id;this.value value;}public int getId() {return id;}public Object getValue() {return value;}Overridepublic String toString() {return Message{ id id , value value };}
} 某次的运行结果
21:17:06 [生产者] c.test - 添加了Message{id5, valuev5}
21:17:06 [生产者] c.test - 添加了Message{id2, valuev2}
21:17:06 [生产者] c.test - 添加了Message{id3, valuev3}
21:17:06 [生产者] c.test - 队列满了
21:17:06 [生产者] c.test - 队列满了
21:17:07 [消费者] c.test - 取出来了Message{id5, valuev5}
21:17:07 [生产者] c.test - 添加了Message{id1, valuev1}
21:17:07 [生产者] c.test - 队列满了
21:17:08 [消费者] c.test - 取出来了Message{id2, valuev2}
21:17:08 [生产者] c.test - 添加了Message{id4, valuev4}
21:17:09 [消费者] c.test - 取出来了Message{id3, valuev3}
21:17:10 [消费者] c.test - 取出来了Message{id1, valuev1}
21:17:11 [消费者] c.test - 取出来了Message{id4, valuev4}
21:17:12 [消费者] c.test - 队列空了