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.
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
});
}
~~> 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
Related
Hi all I want to create a job queue to execute multiple task.but,my requirement is i should be able to add tasks to that job queue any time and all those tasks should be executed sequentially. I searched some solutions in internet and found these two links 1)Java Thread Pool Executor Example 2)Java Executor Framework Tutorial and Best Practices. But i can't use both of these solution.Because after starting Executor service I can't add new task to the service. Because we know that It may throw InterruptedException or ConcurrentModificationException.
You can use a BlockingQueue to keep waiting in a separate thread until one or more Runnable show up.
public class Mainer {
private static final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(15);
public static void main(String[] args) {
Thread t = new Thread(() -> {
while (true) {
try {
queue.take().run();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
for (int i = 0; i < 10; i++) {
queue.add(() -> {
System.out.println("Hello");
});
}
}
}
I think that you should be using an ExecutorService.
It maintains a queue of tasks to be run. You can provide your own queue if you need to.
New tasks can be added at any time using the submit method.
Futures may be obtained when submitting tasks.
Tasks may be run one at a time, or in parallel using a pool of worker threads.
If you use multiple threads, the various executor service implementations provide different pool management strategies.
There are operations for draining and shutting down the service.
If you want an ExecutorService that will always run the tasks one at a time, make sure that you specify a thread pool with a maximum size of one thread.
you please give some example links
The javadocs have examples.
I don't understand these objections that you raised:
But I can't use both of these solution. Because after starting ExecutorService I can't add new task to the service.
Yes you can. That is what ExecutorService.submit(...) does.
Because we know that it may throw InterruptedException ...
It will only throw InterruptedException if your application does something to cause that to happen; e.g. shutting down the ExecutorService using shutdownNow(). (If you don't want that, you can use shutdown() instead, or simply not shut down the executor at all. Refer to the javadocs for more details.)
Anyway, your code can deal with the exception.
or ConcurrentModificationException.
AFAIK, the only scenario where an ExecutorService can throw ConcurrentModificationException is if you are using a custom Queue class that isn't implemented properly.
I have a cached thread pool where new tasks are spawned in rather unpredictable manner. These tasks don't generate any results (they are Runnables rather than Callables).
I would like to have an action to be executed whenever the pool has no active workers.
However I don't want to shutdown the pool (and obviously use awaitTermination) because I would have to reinitialize it again when a new task arrives (as it could arrive unpredictably, even during the shutdown).
I came up with the following possible approaches:
Have an extra thread (outside the pool) which is spawned whenever a new task is spawned AND the ThreadPoolExecutor had no active workers. It should then continually check the getActiveWorkers() until it returns 0 and if yes, execute the desired action.
Have some thread-safe queue (which one?), where the Future of every newly spawned task is added. Whenever there's at least one entry in the queue, spawn an extra thread (outside the pool) which waits until the queue is empty and executes the desired action.
Implement a PriorityBlockingQueue to use with the pool and assign the worker threads higher priority than to the thread (now from inside the pool) which executes the desired action.
My question:
I was wondering if there is some cleaner solution, which uses some nice synchronization object (like CountDownLatch, which however cannot be used here, because I don't know the number of tasks in advance) ?
If I were you, I would implement a decorator for your thread pool that keeps track of the scheduled tasks and slighlig modifies the tasks that are run. This way, whenever a Runnable is scheduled, you can instead schedule another, decoarated Runnable which is capable of tracing its own process.
This decorator would look something like:
class RunnableDecorator implements Runnable {
private final Runnable delegate;
// this task counter must be increased on any
// scheduling of a task by the thread pool
private final AtomicInteger taskCounter;
// Constructor omitted
#Override
public void run() {
try {
delegate.run();
} finally {
if (taskCounter.decrementAndGet() == 0) {
// spawn idle action
}
}
}
}
Of course, the thread pool has to increment the counter every time a task is scheduled. Thus, the logic for this must not be added to the Runnable but to the ThreadPool. Finally, it is up to you to decide if you want to run the idle action in the same thread or if you want to provide a reference to the executing thread pool to run a new thread. If you decide the latter, note however that the completion of the idle action would then trigger another idle action. You might however also provide a method for a sort of raw scheduling. You could also add the decoration to the thread queue what however makes it harder to provide this sort of raw scheduling.
This approach is non-blocking and does not mess with your code base too much. Note that the tread pool does not start an action when it is created and therefore empty by definition.
If you look at the source behind Executors.newCachedThreadPool(), you can see how it's created with a ThreadPoolExecutor. Using that, override the execute and afterExecute methods to add a counter. This way the increment and decrement logic is isolated in one location. Ex:
ExecutorService executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>()) {
private AtomicInteger counter = new AtomicInteger(0);
#Override
public void execute(Runnable r) {
counter.incrementAndGet();
super.execute(r);
}
#Override
public void afterExecute(Runnable r, Throwable t) {
if (counter.decrementAndGet() == 0) {
// thread pool is idle - do something
}
super.afterExecute(r, t);
}
};
I need to execute a queue of thread. I need that only one thread is in execution and then put other thread in a queue and when the current thread is completed I need to pass to the first in the queue.
I need that to implement live search on my JTable. The table holds 50.000 rows so without this method the performance are really bad. I' ve no idea how to implement it. Anyone can help me? Thanks!
Use a single-threaded Executor from Executors.newSingleThreadExecutor(). You can pass your jobs as Runnable objects to the Executor and let it do the work for you.
private final Executor executor = Executors.newSingleThreadExecutor();
public void doSomethingWith(final Object obj) {
executor.execute(new Runnable() {
public void run() {
// Do something with obj
}
});
}
Put the code you want to run once-at-a-time in the run method.
SingleThreadExecutor from java.util.concurrency is the answer to your question...
- It has a Thread size of one....
- Complete 1st task first before moving to 2nd,
- It maintains its own hidden queue to keep the track of the task remaining with it...
I have the following Foo class that uses FooProcessor class. So what i want to do is, while running cp1 instance process method, in parallel I want to run cp2.process().
public class Foo {
public static void main(String [] args){
FooProcessor cp1 = new FooProcessor();
FooProcessor cp2 = new FooProcessor();
cp1.process();
// in parallel process cp2.process();
}
}
public class FooProcessor {
public void process(){
System.out.println("Processing..");
}
}
However, i want cp1 sequentially, so i want it to run and complete, if cp2 doesnt complete or fails it is fine. If it doenst fail i want to join the results. It is not returning anything in this sample but I want to return result.
For this purpose, should is use TaskExecutor? or Thread?
I want only cp2 to run in parallel to cp1. or if i add more lets say cp3, i want that to run in parallel as well to cp1.
The way I would implement it, in summary :
run your different processes via an ExecutorService, for example ExecutorService executor = Executors.newFixedThreadPool(nThreads);
store the Futures of all your tasks in a List (returned by ExecutorService#submit)
wait for future1.get() to complete, where future1 is the future linked to cp1
once get returns (cp1 has finished) cancel all the other futures, (or shutdownNow the executor service if you don't need the executor any longer)
for that cancellation process to work, your cp2, cp3 etc need to implement an interruption policy that makes them stop what they are doing asap.
Thread would be a good choice...Something like a method that accepts a new threads and start them...
According to https://stackoverflow.com/a/2269177/454167,
You can use something like a AsyncTaskExecutor[1], which returns a Future object. You can then wait on the Future to know if cp2 returns success.
[1] http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/core/task/AsyncTaskExecutor.html#submit%28java.lang.Runnable%29
You can of course use plain and simple Threads
If you know you need to add more methods to the processor class, and for a given instance of it to keep execution order - let's say you first run method foo, and then run method bar, and you want them to run asynchronously, but keep execution order (first foo, then bar), I would consider to use Active Object pattern.
I recommend also using this approach because for the user of the processor class it will hide implementation details.
In addition, consider providing a decorator/wrapper that will provide this async ability to your objects - this way you will be able to control which object is run asynchronously and which isn't, and you will not have to "pollute" your Processor class with code needed for asynchronous invocation.
An example of usage in this case will be -
AsyncProcessor ap = new AsyncProcessor(p1);
ap.process(); //executed asynchronously
Proccessor p2 = new Processor();
p2.process(); //executed synchronously
Another apporach is to use as you mentioned, an executor -
This can be achieved by implementing a thread pool and pushing "execution units to it".
An execution unit will contain the target object (cp1, cp2, ...) and the method to execute (currently - only process)
The threads will take "an execution unit" from the queue and run them.
The implementation is similar to active object, but the "interface" for the user is different as it uses a "TaskExecutor" class to provide it "execution units"
If you're writing your own standalone application, using threads might be the easiest way forward. If you're in a Java EE environment, you should not create your own Thread objects, but use some other mechanism (such as sending messages and have message listeners process the signals you send). This is to have the Java EE container control resource utilization such as thread pools.
Example of using Threads:
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
executeSomeCodeInP1();
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
executeSomeCodeInP2();
}
});
t1.start();
t2.start();
// if you want to wait for both threads to finish before moving on,
// "join" the current thread
t1.join();
t2.join();
I have question about the Java threads. Here is my scenario:
I have a thread calling a method that could take while. The thread keeps itself on that method until I get the result. If I send another request to that method in the same way, now there are two threads running (provided the first did not return the result yet). But I want to give the priority to the last thread and don't want to get the results from the previously started threads. So how could I get rid of earlier threads when I do not have a stop method?
The standard design pattern is to use a local variable in the thread that can be set to stop it:
public class MyThread extends Thread {
private volatile boolean running = true;
public void stop() {
running = false;
}
public void run() {
while (running) {
// do your things
}
}
}
This way you can greacefully terminate the thread, i.e. without throwing an InterruptedException.
The best way really depends on what that method does. If it waits on something, chances are an interrupt will result in an InterruptedException which you handle and cleanly exit. If it's doing something busy, it won't:
class Scratchpad {
public static void main(String[] a) {
Thread t = new Thread(new Runnable() {
public void run() {doWork();}
});
t.start();
try {
Thread.sleep(50);
} catch (InterruptedException ie) {}
t.interrupt();
}
private static void doWork() {
for ( long i = 1; i != 0; i *=5 );
}
}
In the case above, the only viable solution really is a flag variable to break out of the loop early on a cancel, ala #inflagranti.
Another option for event-driven architectures is the poison-pill: if your method is waiting on a blocking queue for a new item, then you can have a global constant item called the "poison-pill" that when consumed (dequeued) you kill the thread:
try {
while(true) {
SomeType next = queue.take();
if ( next == POISON_PILL ) {
return;
}
consume(next);
}
} catch //...
EDIT:
It looks like what you really want is an executor service. When you submit a job to an executor service, you get back a Future which you can use to track results and cancel the job.
You can interrupt a Thread, its execution chain will throw an InterruptedException most of the time (see special cases in the documentation).
If you just want to slow down the other thread and not have it exit, you can take some other approach...
For one thing, just like exiting you can have a de-prioritize variable that, when set, puts your thread to sleep for 100ms on each iteration. This would effectively stop it while your other thread searched, then when you re-prioritize it it would go back to full speed.
However, this is a little sloppy. Since you only ever want one thing running but you want to have it remember to process others when the priority one is done, you may want to place your processing into a class with a .process() method that is called repeatedly. When you wish to suspend processing of that request you simply stop calling .process on that object for a while.
In this way you can implement a stack of such objects and your thread would just execute stack.peek().process(); every iteration, so pushing a new, more important task onto the stack would automatically stop any previous task from operating.
This leads to much more flexible scheduling--for instance you could have process() return false if there is nothing for it to do at which point your scheduler might go to the next item on the stack and try its' process() method, giving you some serious multi-tasking ability in a single thread without overtaxing your resources (network, I'm guessing)
There is a setPriority(int) method for Thread. You can set the first thread its priority like this:
Thread t = new Thread(yourRunnable);
t.start();
t.setPriority(Thread.MIN_PRIORITY); // The range goes from 1 to 10, I think
But this won't kill your thread. If you have only two threads using your runnable, then this is a good solution. But if you create threads in a loop and you always sets the priority of the last thread to minimum, you will get a lot of threads.
If this is what is application is going to do, take a look at a ThreadPool. This isn't an existing class in the Java API. You will have create one by yourself.
A ThreadPool is another Thread that manages all your other Threads the way you want. You can set a maximum number of running Threads. And in that ThreadPool, you can implement a system that manages the Thread priority automatically. Eg: You can make that older threads gain more priority, so you can properly end them.
So, if you know how to work with a ThreadPool, it can be very interesting.
According to java.lang.Thread API, you should use interrupt() method and check for isInterrupted() flag while you're doing some time-consuming cancelable operation. This approach allows to deal with different kind of "waiting situations":
1. wait(), join() and sleep() methods will throw InterruptedExcetion after you invoke interrupt() method
2. If thread blocked by java.nio.channels.Selector it will finish selector operation
3. If you're waiting for I/O thread will receive ClosedByInterruptException, but in this case your I/O facility must implement InterruptibleChannel interface.
If it's not possible to interrupt this action in a generic way, you could simply abandon previous thread and get results from a new one. You could do it by means of java.util.concurrent.Future and java.util.concurrent.ExecutorService.
Cosider following code snippet:
public class RequestService<Result> {
private ExecutorService executor = Executors.newFixedThreadPool(3);
private Future<Result> result;
public Future<Result> doRequest(){
if(result !=null){
result.cancel(true);
}
result = executor.submit(new Callable<Result>() {
public Result call() throws Exception {
// do your long-running service call here
}
});
return result;
}
}
Future object here represents a results of service call. If you invoke doRequest method one more time, it attempts to cancel previous task and then try to submit new request. As far as thread pool contain more than one thread, you won't have to wait until previous request is cancelled. New request is submitted immediately and method returns you a new result of request.