多任务,多打印机厨打服务代码样例

简单的模型实现,实际业务中比较复杂,需要考虑打印失败,连接打印机失败等问题

逻辑图

img_tc_1740291715420429404.png

代码

启动类

package com.nsk666.print;
 
/**
 * @author niushuaikui
 * @description TODO
 * @date 2024-05-06
 */
public class PrinterTest {

    public static void main(String[] args) {
        PrintAttribute.printeIPList.add("192.168.5.1");
        PrintAttribute.printeIPList.add("192.168.5.2");
        new StartupPrint().start();
    }
}

主线程类

package com.nsk666.print;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * @author niushuaikui
 * @description 打印机主线程,启动打印机工作线程
 * @date 2024-05-06
 */
@Slf4j
public class StartupPrint extends Thread{
    // 主线程运行标志
    private boolean isRunning = true;
    // 线程休眠时间
    int sleepTime = 10000;
    @Override
    public void run() {
        log.info("主线程启动");
        startUpPrintThread();
        while (isRunning){
            List<String> ips = checkNotFinish();
            if (!ips.isEmpty()){
                log.info("有未完成的打印任务,等待"+sleepTime/1000+"秒后重试");
                try {
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                continue;
            }
            // 获取打印机任务
            PrintAttribute.printTaskList = PrintAttribute.getPrintTaskList();
            if (PrintAttribute.printTaskList.isEmpty()){
                log.info("没有打印任务,等待"+sleepTime/1000+"秒后重试");
                try {
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                continue;
            }
            log.info("获取到打印任务,开始分配任务本次任务数:"+PrintAttribute.printTaskList.size());
            for (PrintWork printWork : PrintAttribute.workList) {
                printWork.startPrint();
            }
            log.info("所有打印机工作线程任务分配完成");
        }
    }

    /**
     * 检查未完成的打印任务
     */
    private List<String> checkNotFinish() {
        List<String> finishList = new ArrayList<>();
        for (PrintWork work : PrintAttribute.workList) {
            if (!work.isFinish()){
                finishList.add(work.getIp());
            }
        }
        return finishList;
    }

    /**
     * 启动打印机工作线程
     */
    private void startUpPrintThread() {
        if (PrintAttribute.printeIPList.isEmpty()){
            log.info("没有设置打印机");
            return;
        }
        for (String ip : PrintAttribute.printeIPList) {
            PrintWork printWork = new PrintWork(ip);
            printWork.start();
            PrintAttribute.workList.add(printWork);
            log.info("启动打印机工作线程:" + ip+"成功");
        }
        log.info("所有打印机工作线程启动完成");
    }
}

打印机工作线程类

package com.nsk666.print;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * @author niushuaikui
 * @description 打印机工作线程
 * @date 2024-05-06
 */
@Slf4j
public class PrintWork extends Thread {
    private String ip;
    private final Object lock = new Object();
    private Printer printer  ;
    private boolean isFinish = true;
    private ConcurrentLinkedQueue<PrintTask> task = new ConcurrentLinkedQueue<>();

    public PrintWork(String ip ) {
        this.ip = ip;
        init();
    }

    @Override
    public void run() {
       while (true){
           pausePrint();
           log.info(ip + "被唤醒,开始打印任务");
           addTask(PrintAttribute.printTaskList);
           log.info(ip + "获取到任务:"+task.size()+"个");
           List<PrintTask> tasks = printTask();
           task.removeAll(tasks);
       }
    }

    public void addTask(List<PrintTask> taskList){
        isFinish = false;
        for (PrintTask printTask : taskList) {
            if (printTask.getIp().equals(ip)){
                task.add(printTask);
            }
        }
    }
    /**
     * 初始化打印机
     */
    public void init() {
        try {
            printer = new Printer();
            printer.setIp(ip);
            printer.connect();
            printer.disconnect();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public  List<PrintTask> printTask()  {
        List<PrintTask> finishTask = new ArrayList<>();
        try {
            isFinish = false;
            for (PrintTask s : task) {
                printer.connect();
                Thread.sleep(1000);
                printer.print(s.getTask());
                printer.disconnect();
                finishTask.add(s);
            }
            isFinish = true;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return finishTask;
    }
    /**
     * 暂停打印
     */
    public void pausePrint() {
        synchronized (lock) {
            log.info(ip + "pause print");
            try {
                lock.wait();
                setFinish(true);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 开始打印
     */
    public void startPrint() {
        synchronized (lock) {
            lock.notify();
            setFinish(false);
        }
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public boolean isFinish() {
        return isFinish;
    }

    public void setFinish(boolean finish) {
        isFinish = finish;
    }
}

打印任务类

package com.nsk666.print;

/**
 * @author niushuaikui
 * @description 打印机任务类
 * @date 2024-05-06
 */
public class PrintTask {
    private String ip;
    private String task;

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getTask() {
        return task;
    }

    public void setTask(String task) {
        this.task = task;
    }
}

全局变量类

package com.nsk666.print;

import java.util.ArrayList; 
import java.util.List; 

/**
 * @author niushuaikui
 * @description 打印公共属性集合类
 * @date 2024-05-06
 */
public class PrintAttribute {
    public static List<String> printeIPList = new ArrayList<>();
    public static List<PrintWork> workList = new ArrayList<>();
    public static  List<PrintTask> printTaskList = new ArrayList<>();

    /**
     * 获取打印机任务
     */
    public static List<PrintTask> getPrintTaskList(){
        int times = (int) (Math.random()* 20);
        List<PrintTask> tasks = new ArrayList<>();
        for (int i = 0; i < times; i++) {
            int index = (int) (Math.random()* printeIPList.size());
            String s = printeIPList.get(index);
            PrintTask printTask = new PrintTask();
            printTask.setIp(s);
            printTask.setTask("打印任务"+System.currentTimeMillis());
            tasks.add(printTask);
        }
        return tasks;
    }
}

打印机类

package com.nsk666.print;

import lombok.extern.slf4j.Slf4j;

/**
 * @author niushuaikui
 * @description 打印机类
 * @date 2024-05-06
 */
@Slf4j
public class Printer {
    private String ip;
    private boolean isConnect = false;
    private String port = "9100";

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
    }

    public void connect() throws InterruptedException {
        Thread.sleep(200);
            // log.info("连接打印机: " + getIp() + ":" + getPort
    }

    public void print(String task) throws InterruptedException {
        Thread.sleep(800);
        log.info("任务处理完成: " + getIp() + ":" + getPort());
    }

    public void disconnect() throws InterruptedException {
        Thread.sleep(200);
    }
}

效果

img_tc_1744101715420649243.png