乍一看,您的客户似乎有太多的打印机逻辑。我认为客户的方法更像:
public void printMe() {
printer.print(this);
}
打印机将处理所有可用的检查、排队和调度:
public synchronized boolean print(Client c, Something something) {
if(isFair(c) && isAvailable()) {
requestToPrint(something);
}
else {
// queue
// Not sure what "requestToPrintNext" does,
// as it has no argument, like "something"
}
}
同步的打印方法将防止其他客户端相互跳过(下一个客户端将被阻止,直到当前客户端的方法完成)。正如其他海报所提到的,如果该requestToPrint
方法需要很长时间,您可以将其线程化(只需确保它首先以某种方式将 isAvailable 设置为 false,以便下一个客户端将正确排队)。
上述print
方法假设该requestToPrint
方法只是简单地触发一个打印作业,并且不会阻塞整个打印操作。示例实现可能类似于:
public void requestToPrint(Client c) {
setAvailable(false);
Thread job = new Thread(new Runnable() {
@Override
public void run() {
// The actual print work
setAvailable(true);
}
});
job.start();
}
可能值得注意的是,此实现非常特定于该问题的约束。对于更通用的方法,具有单个工作线程来服务该队列的单个打印队列(如其他答案所引用)总体上会更干净。一个非常简单的骨架是:
public void print(Client c) {
synchronized(queue) {
queue.add(c);
}
}
public class PrintWorker implements Runnable {
@Override
public void run() {
while(true) {
Client c = null;
synchronized(queue) {
if(!queue.isEmpty()) {
c = queue.remove(0);
}
}
if(c != null) {
// do print work
}
else {
// maybe add sleep or wait here
// to keep thread from spinning
// too fast and burning CPU
}
}
}
}