多任务,多打印机厨打服务代码样例
简单的模型实现,实际业务中比较复杂,需要考虑打印失败,连接打印机失败等问题
逻辑图
代码
启动类
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);
}
}