Queue print jobs in a separate single Thread for JavaFX

主宰稳场 提交于 2020-01-05 04:31:12

问题


currently I am experimenting with Concurrency in Java/JavaFX. Printing must run in a different thread otherwise it will make the JavaFX main thread freeze for a couple seconds. Right now my printing is done with this simplified example.

public void print(PrintContent pt) {
    setPrintContent(pt);

    Thread thread = new Thread(this);
    thread.start();
}

@Override
public void run() {
    // send content to printer
}

With this code I am sending many print jobs parallel to my printer. Therefore I get the error telling me that my printer can only handle 1 print job at a time. Since I know that Threads cannot be reused, I would like to know if there is a possibility to queue up Threads, so that my printer only handles one print job at a time.

Thank you very much for your effort and your time.


回答1:


~~> WAY 1

You can implement your own BlockingQueue read this is very useful or use a default implementation from Java libraries tutorial

So after reading the above links,you add a method in your class like

public void addJob(Object job){   
  queue.put(job); 
}

Secondly you implement a Thread that is running into an infinite while loop.Inside it you call the method

queue.take();

When the queue is empty this Thread is blocked waiting until a new Object is added,so you dont have to worry about spending cpu time.

Finally you can set some upper bounds so for example queue can contain .. 27 items.

Mention that in case of Thread failure you have to recreate it manually.

~~>WAY 2 Better Approach

You can use an Executors Interface:

ExecutorService executorService1 = Executors.newSingleThreadExecutor(); 

From documentation:

Creates an Executor that uses a single worker thread operating off an unbounded queue. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.) Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time.

With the method below you retrieve a result if the job has successfully done.

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());

If future.get() returns null, the job has been done successfully.

Remember to call executorService.shutdown(); because the active threads inside this ExecutorService may prevent the JVM from shutting down.

Full tutorial here




回答2:


Use a single threaded executor to execute the print jobs. It will create one (and only one) background thread and queue the jobs:

// 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
    });
}


来源:https://stackoverflow.com/questions/39102638/queue-print-jobs-in-a-separate-single-thread-for-javafx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!