我试图模拟打印机设置,其中顺序完成单色和彩色打印。 删除print语句时,我的代码会产生意外结果。
有问题的函数是request()。 我已经研究了这个并且遇到了很多文章,其中讨论了这个问题围绕线程同步和向函数添加同步关键字,或者使变量有问题。
我相信我的三个主题同时弹出列表并检索与输出没有打印输出相同的数据:
(0) M3 uses head 1 (time: 3)
(0) M3 uses head 2 (time: 3)
(0) M3 uses head 3 (time: 3)
包含打印输出的地方是:
grabbed job M1
grabbed job M2
(0) M1 uses head 1 (time: 4)
grabbed job M3
(0) M2 uses head 2 (time: 5)
(0) M3 uses head 3 (time: 3)
但是,我从这个项目开始就在我的函数中有了synchronized关键字。 我也尝试用函数中的二进制信号量替换关键字。 发现这篇文章内容丰富,但不是我的确切场景的答案:Questions about thread+loop not working without print statement
我的代码:
import java.util.LinkedList;
public class Printer{
public static int TIME = 0;
private static boolean COLOURMODE = true;
private static LinkedList<Job> jobs;
private static Job tempJob;
private PrinterHead printHead1;
private PrinterHead printHead2;
private PrinterHead printHead3;
public Printer(LinkedList<Job> jobs) {
this.jobs = jobs;
printHead1 = new PrinterHead(this,1);
printHead2 = new PrinterHead(this,2);
printHead3 = new PrinterHead(this,3);
printHead1.start();
printHead2.start();
printHead3.start();
}
public static boolean hasJobs(){
if(jobs.isEmpty()){
return false;
}
else{
return true;
}
}
public synchronized Job request(){
tempJob = jobs.peek();
if(COLOURMODE){
if(tempJob.type == 'C'){
//System.out.println("grabbed job " + tempJob.jID);
return jobs.pop();
}
else{
COLOURMODE = false;
printHead1.TIME = TIME;
printHead2.TIME = TIME;
printHead3.TIME = TIME;
}
}
else if(!COLOURMODE){
if(tempJob.type == 'M'){
//System.out.println("grabbed job " + tempJob.jID);
return jobs.pop();
}
else{
COLOURMODE = true;
printHead1.TIME = TIME;
printHead2.TIME = TIME;
printHead3.TIME = TIME;
}
}
return null;
}
}
编辑:添加了PrinterHead类。
import java.util.concurrent.Semaphore;
public class PrinterHead extends Thread {
private static Job job;
public static int TIME = 0;
private int headNum;
private static Printer printer;
private static Semaphore mutex = new Semaphore(1, true);
public PrinterHead(Printer printer, int headNum){
this.headNum = headNum;
this.printer = printer;
}
public void run(){
while(printer.hasJobs()){
job = printer.request();
if (job != null){
print();
if(printer.TIME < job.pages+TIME){
printer.TIME = job.pages+TIME;
}
try{
this.sleep(1000*job.pages);
}
catch(Exception e){
System.out.println("some shit broke in printhead " + headNum);
return;
}
}
}
}
private void print(){
try{
mutex.acquire();
System.out.println("("+TIME+") "+ job.jID+" uses head "+headNum + " (time: "+job.pages+")");
mutex.release();
}
catch(Exception e){
System.out.println("some shit broke in printout " + headNum);
return;
}
}
}
我的Main
创建了一个Printer
个实例和LinkedList
个Job
个。
如果您需要更多,请问我,谢谢。