目前我正在尝试使用Java / JavaFX中的Concurrency。打印必须在不同的线程中运行,否则会使JavaFX主线程冻结几秒钟。现在我的打印完成了这个简化的例子。
public void print(PrintContent pt) {
setPrintContent(pt);
Thread thread = new Thread(this);
thread.start();
}
@Override
public void run() {
// send content to printer
}
使用此代码,我发送的许多打印作业与我的打印机并行。因此,我收到错误告诉我,我的打印机一次只能处理1个打印作业。由于我知道Threads无法重用,我想知道是否有可能排队Threads,这样我的打印机一次只能处理一个打印作业。
非常感谢您的努力和时间。
答案 0 :(得分:4)
使用single threaded executor执行打印作业。它将创建一个(并且只有一个)后台线程并为作业排队:
// it might be better not to make this static; but you need to ensure there is
// only one instance of this executor:
private static final Executor PRINT_QUEUE = Executors.newSingleThreadExecutor();
// ...
public void print(PrintContent pt) {
PRINT_QUEUE.execute(() -> {
// send content to printer
});
}
答案 1 :(得分:1)
~~>方式1
您可以实现自己的BlockingQueue
read this is very useful或使用Java库中的默认实现tutorial
因此,在阅读上述链接后,您可以在类中添加一个方法,如
public void addJob(Object job){
queue.put(job);
}
其次,你实现了一个运行到无限while循环的Thread.Inside它你调用方法
queue.take();
当队列为空时,此线程将被阻塞,等待添加新对象,因此您不必担心花费cpu时间。
最后你可以设置一些上限,例如,队列可以包含.. 27项。
提及在线程失败的情况下,您必须手动重新创建它。
~~>方式2更好的方法
您可以使用Executors界面:
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
来自文档:
创建一个Executor,它使用一个工作线程来操作 无界队列。 (但请注意,如果此单个线程终止 由于在关机之前执行期间出现故障,新的将会 如果需要执行后续任务,取而代之。)任务是 保证按顺序执行,并且不会超过一个任务 在任何特定时间都有效。
使用下面的方法,如果作业成功完成,则检索结果。
Future future = executorService.submit(new Callable(){ public Object call() throws Exception { System.out.println("Asynchronous Callable"); return "Callable Result"; } });
System.out.println("future.get() = " + future.get());
如果future.get()返回null,则作业已成功完成。
记得打电话
executorService.shutdown();
因为此ExecutorService中的活动线程可能会阻止JVM关闭。
完整教程here