使用Java和Java线程进行打印机模拟

3
我有一个任务,需要模拟打印机的行为,其中打印作业可以以不同的时间间隔或同时提交到打印机。因此,这里必须使用thread.start(),打印机将从打印机队列中取出作业并打印,而其它作业则等待它们的轮到。
总共只需要编写3个类:Admin类、PrintRequest类和Printer类。
以下是我的代码:
public class Admin{
    public static void main(String[] args){
        Printer printer = new Printer();
        for(int x=0; x<10;x++){
            PrintRequest printRequest = new PrintRequest(x,printer);
            printRequest.start();
        }
    }
}

public class PrintRequest extends Thread {
    private static int duration; 
    private static int id;
    private static Printer printer;

    public PrintRequest(int id, Printer printer){
        duration = (int)Math.ceil(Math.random()*1000);
        this.id = id;
        this.printer = printer;
    }
    public void run(){
        printer.printJob(id, duration);
    }
}

public class Printer{
    public static synchronized void printJob(int id, int duration){
        System.out.println("Printing " + id);
        try{Thread.sleep(duration);}
        catch(InterruptedException ex){System.out.println(ex.getMessage());}
        System.out.println("Completed printing " + id);
    }
}

输出结果存在一些问题,它并不是我想要的从ID 0-10打印的结果。相反,输出结果如下图所示:

enter image description here

那么我的代码有什么问题呢?我认为问题出在Admin类循环上,但我应该如何改进代码,使其正常工作呢?


那么您建议我将打印机类扩展为线程,对吗?关于队列的第二部分,有没有其实现的示例?提前致谢! - RandomDude
@RandomDude 例如,可以参考 https://kodejava.org/how-do-i-use-the-blockingqueue-object/ - Alexei Kaigorodov
“Re, '… 将打印机类扩展为线程...' 这样做可以工作,但更好的设计(特别是如果您试图构建真正的商业质量软件),是将打印机的概念与运行它的线程分开。我会定义一个 Printer 类,其构造函数需要一个 PrintQueue 参数和一个 run() 方法。我的 Printer 不知道任何关于线程的信息。然后,我会编写一个更高级的“粘合”例程,用于创建 PrintQueue 实例、创建一个将为其服务的 Printer、创建一个运行 PrinterThread,并将它们全部连接起来。” - Solomon Slow
PS:我定义它的最大原因是为了测试。我通常必须测试我编写的软件。测试一个不知道线程的“打印机”比测试一个“是”线程的“打印机”要容易得多。 - Solomon Slow
问题的第二部分是尝试使用ReentrantLock,其中可重入锁似乎为打印机函数创建了某种形式的队列。感谢大家的建议! - RandomDude
显示剩余2条评论
1个回答

2
你的代码存在几个问题。
首先,我认为你应该查找一下什么是静态变量。目前,所有的PrintRequests都有相同的id,我不认为这是你想要的。
此外,生成睡眠时间的代码只会生成0到1000之间的数字。这意味着作业持续时间不到一秒钟,输出可能与你的预期不符。
请将你的代码修改为:
duration = (int)(1000 + (Math.random()*5000));

最初的回答给我以下输出
Printing 0
Printing 2
Printing 1
Printing 4
Printing 5
Printing 6
Printing 7
Printing 8
Printing 3
Printing 9
Completed printing 6
Completed printing 4
Completed printing 8
Completed printing 2
Completed printing 9
Completed printing 3
Completed printing 1
Completed printing 0
Completed printing 7
Completed printing 5

你可能会问:为什么打印顺序不一致?
这是因为在你的循环中,Java无法按顺序启动线程。如果你真的想要有序打印,就需要添加一些机制来增强它。原始答案翻译成“最初的回答”。

嗯,我会尝试的!看起来就是我想要的,而且我明白它不应该顺序运行! - RandomDude

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接