首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 模擬打印機佇列:單例模式、LinkedList 任務佇列、回調介面

     編輯:Java 程式設計入門

需求

多執行緒環境下,多個來源提交列印任務,打印機按順序/優先級處理,支援同步回調通知完成。

核心類設計

// 任務實體
class PrintTask {
    final String docId;
    final byte[] data;
    final int priority; // 越大越優先
    final Consumer callback;

    PrintTask(String docId, byte[] data, int priority, Consumer cb) {
        this.docId = docId; this.data = data; this.priority = priority; this.callback = cb;
    }
}

// 佇列管理器 (單例 + 執行緒安全)
class PrintQueue {
    private static final PrintQueue INSTANCE = new PrintQueue();
    private final LinkedList queue = new LinkedList<>();
    private final Object lock = new Object();
    private volatile boolean running = false;

    private PrintQueue() {}

    public static PrintQueue getInstance() { return INSTANCE; }

    // 普通提交 (尾部)
    public void submit(PrintTask task) {
        synchronized (lock) { queue.addLast(task); lock.notify(); }
    }

    // 優先/緊急提交 (頭部)
    public void submitUrgent(PrintTask task) {
        synchronized (lock) { queue.addFirst(task); lock.notify(); }
    }

    // 處理迴圈 (單獨執行緒啟動)
    public void start(Consumer processor) {
        synchronized (lock) {
            if (running) return;
            running = true;
        }
        new Thread(() -> {
            while (true) {
                PrintTask task;
                synchronized (lock) {
                    while (queue.isEmpty()) {
                        try { lock.wait(); } catch (InterruptedException e) { return; }
                    }
                    task = queue.removeFirst();
                }
                processor.accept(task); // 實際打印邏輯
                if (task.callback != null) task.callback.accept(task);
            }
        }, "Print-Worker").start();
    }

    public void shutdown() {
        synchronized (lock) { running = false; lock.notifyAll(); }
    }
}

使用範例

public class PrintDemo {
    public static void main(String[] args) {
        PrintQueue queue = PrintQueue.getInstance();

        // 啟動處理器 (模擬打印耗時)
        queue.start(task -> {
            System.out.println("打印中: " + task.docId);
            try { Thread.sleep(500); } catch (InterruptedException ignored) {}
            System.out.println("完成: " + task.docId);
        });

        // 提交任務
        for (int i = 0; i < 5; i++) {
            final int n = i;
            queue.submit(new PrintTask("Doc-" + n, new byte[0], 0, t -> 
                System.out.println("回調: " + t.docId + " 完成")));
        }

        // 緊急插隊
        queue.submitUrgent(new PrintTask("URGENT", new byte[0], 10, null));

        // 等待演示結束
        try { Thread.sleep(3000); } catch (InterruptedException ignored) {}
        queue.shutdown();
    }
}

擴展方向

  • 優先級佇列:`PriorityQueue` 配合 `Comparator.comparingInt(PrintTask::getPriority).reversed()`。
  • 持久化:任務序列化寫入資料庫/文件,重啟恢復。
  • 分散式:Redis List/RabbitMQ/Kafka 作為外部佇列,多打印機節點消費。
  • 狀態追蹤:`PENDING` → `PRINTING` → `DONE/FAILED`,提供 REST 查詢介面。
  • 背壓控制:佇列達高水位拒絕/阻塞提交,防止 OOM。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved