1.背景
面試官問,假設讓你設計一個隊列,你的思路是...
2.代碼
package com.ldp.demo01; import com.common.MyThreadUtil; import lombok.extern.slf4j.Slf4j; import java.util.LinkedList; /** * @author 姿勢帝-博客園 * @address https://www.cnblogs.com/newAndHui/ * @WeChat 851298348 * @create 01/31 8:24 * @description */ @Slf4j public class Test08MessageQueue { /** * 測試自定義的隊列 * * @param args */ public static void main(String[] args) { // 創建隊列 MessageQueue queue = new MessageQueue(2); // 模擬4個生產者參數數據到隊列 for (int i = 0; i < 4; i++) { int n = i + 1; new Thread(() -> { int m = 1; // 不停的循環放入數據 while (true) { int k = n * 1000 + m; Message message = new Message(k, "消息-" + k); log.info("放入的消息是:{}", message); queue.put(message); m++; } }, "生產者-" + n).start(); } // 模擬2個消費者到隊列中取數據 for (int i = 0; i < 1; i++) { int n = i + 1; new Thread(() -> { // 每個消費者都是不停的取數據 while (true) { // 每隔2秒取一次 MyThreadUtil.sleep(2); Message message = queue.take(); log.info("取到的消息是:{}", message); } }, "消費者-" + n).start(); } } } @Slf4j class MessageQueue { /** * 隊列的容量 */ private Integer capacity; /** * 裝消息的隊列 */ private LinkedList<Message> list = new LinkedList<>(); public MessageQueue(Integer capacity) { this.capacity = capacity; } /** * 獲取一條消息 * * @return */ public Message take() { synchronized (list) { while (list.isEmpty()) { try { // log.debug("無數據,等待中...."); list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 取出頭部消息,並刪除 Message message = list.removeFirst(); // 通知放入隊列 list.notifyAll(); return message; } } /** * 放入一條數據 * * @param message */ public void put(Message message) { synchronized (list) { while (list.size() >= capacity) { try { // log.debug("隊列已滿,當前隊列數:{},最大隊列數:{}", list.size(), capacity); list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 放入隊列 list.addLast(message); // 通知消費者取數據 list.notifyAll(); } } } /** * 消息對象 * 使用final不讓其被繼承,避免修改消息 */ final class Message { private Integer id; private Object object; /** * 提供一個構造方法 * * @param id * @param object */ public Message(Integer id, Object object) { /** * 消息id */ this.id = id; /** * 具體的消息內容 */ this.object = object; } /** * 只提供獲取方法,讓消息不可以修改 * * @return */ public Integer getId() { return id; } public Object getObject() { return object; } @Override public String toString() { return "Message{" + "id=" + id + ", object=" + object + '}'; } }