在单独的Thread for JavaFX中将打印作业排队

时间:2016-08-23 13:30:03

标签: java multithreading javafx concurrency queue

目前我正在尝试使用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,这样我的打印机一次只能处理一个打印作业。

非常感谢您的努力和时间。

2 个答案:

答案 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