I have a thread that needs to be executed every 10 seconds. This thread contains several calls (12 - 15) to a database on another server. Additionally, it also accesses around 3 files. Consequently, there will be quite a lot of IO and network overhead.
What is the best strategy to perform the above?
One way would be to use the sleep method along with a while loop, but that would be a bad design.
Will a class similar to Timer be helpful in this case? Also, would it be better to create a couple of more threads (one for IO and one for JDBC), instead of having them run in one thread?
I find that a ScheduledExecutorService is an excellent way to do this. It is arguably slightly more complex than a Timer, but gives more flexibility in exchange (e.g. you could choose to use a single thread or a thread pool; it takes units other than solely milliseconds).
ScheduledExecutorService executor =
Executors.newSingleThreadScheduledExecutor();
Runnable periodicTask = new Runnable() {
public void run() {
// Invoke method(s) to do the work
doPeriodicWork();
}
};
executor.scheduleAtFixedRate(periodicTask, 0, 10, TimeUnit.SECONDS);
One option is to create a ScheduledExecutorService to which you can then schedule your job:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
ex.scheduleWithFixedDelay(...);
If you did decide to have multiple threads, then you can create a ScheduledExecutorService with more threads (again, via the Executors class).
In terms of how many threads and what you put in each thread, in terms of performance, I'd say this depends on:
for your particular application, can one thread genuinely "do work" while another one is waiting for I/O?
would your multiple threads ultimately "thrash the same resource" (e.g. read from files in different locations on the same dsk) and thus slow one another down, or would they be simultaneously hitting different resources?
Have a look at the Timer and TimerTask classes. They are exactly what you want.
You can make a TimerTask implementation that takes your thread object in a constructor.
The run method will then call the threads run method.
// Perhaps something like this
Timer t = new Timer();
t.scheduleAtFixedRate(yourTimerTask, 0, 10 * 1000);
// Hopefully your task takes less than 12 seconds
Related
This question already has answers here:
When should we use Java's Thread over Executor?
(7 answers)
Closed 7 years ago.
In Java, both of the following code snippets can be used to quickly spawn a new thread for running some task-
This one using Thread-
new Thread(new Runnable() {
#Override
public void run() {
// TODO: Code goes here
}
}).start();
And this one using Executor-
Executors.newSingleThreadExecutor().execute(new Runnable(){
#Override
public void run() {
// TODO: Code goes here
}
});
Internally, what is the difference between this two codes and which one is a better approach?
Just in case, I'm developing for Android.
Now I think, I was actually looking for use-cases of newSingleThreadExecutor(). Exactly this was asked in this question and answered-
Examples of when it is convenient to use Executors.newSingleThreadExecutor()
Your second example is strange, creating an executor just to run one task is not a good usage. The point of having the executor is so that you can keep it around for the duration of your application and submit tasks to it. It will work but you're not getting the benefits of having the executor.
The executor can keep a pool of threads handy that it can reuse for incoming tasks, so that each task doesn't have to spin up a new thread, or if you pick the singleThread one it can enforce that the tasks are done in sequence and not overlap. With the executor you can better separate the individual tasks being performed from the technical implementation of how the work is done.
With the first approach where you create a thread, if something goes wrong with your task in some cases the thread can get leaked; it gets hung up on something, never finishes its task, and the thread is lost to the application and anything else using that JVM. Using an executor can put an upper bound on the number of threads you lose to this kind of error, so at least your application degrades gracefully and doesn't impair other applications using the same JVM.
Also with the thread approach each thread you create has to be kept track of separately (so that for instance you can interrupt them once it's time to shutdown the application), with the executor you can shut the executor down once and let it handle its threads itself.
The second using an ExecutorService is definitely the best approach.
ExecutorService determines how you want your tasks to run concurrently. It decouples the Runnables (or Callables) from their execution.
When using Thread, you couple the tasks with how you want them to be executed, giving you much less flexibility.
Also, ExecutorService gives you a better way of tracking your tasks and getting a return value with Future while the start method from Thread just run without giving any information. Thread therefore encourages you to code side-effects in the Runnable which may make the overall execution harder to understand and debug.
Also Thread is a costly resource and ExecutorService can handle their lifecycle, reusing Thread to run a new tasks or creating new ones depending on the strategy you defined. For instance: Executors.newSingleThreadExecutor(); creates a ThreadPoolExecutor with only one thread that can sequentially execute the tasks passed to it while Executors.newFixedThreadPool(8)creates a ThreadPoolExecutor with 8 thread allowing to run a maximum of 8 tasks in parallel.
You already have three answers, but I think this question deserves one more because none of the others talk about thread pools and the problem that they are meant to solve.
A thread pool (e.g., java.util.concurrent.ThreadPoolExecutor) is meant to reduce the number of threads that are created and destroyed by a program.
Some programs need to continually create and destroy new tasks that will run in separate threads. One example is a server that accepts connections from many clients, and spawns a new task to serve each one.
Creating a new thread for each new task is expensive; In many programs, the cost of creating the thread can be significantly higher than the cost of performing the task. Instead of letting a thread die after it has finished one task, wouldn't it be better to use the same thread over again to perform the next one?
That's what a thread pool does: It manages and re-uses a controlled number of worker threads, to perform your program's tasks.
Your two examples show two different ways of creating a single thread that will perform a single task, but there's no context. How much work will that task perform? How long will it take?
The first example is a perfectly acceptable way to create a thread that will run for a long time---a thread that must exist for the entire lifetime of the program, or a thread that performs a task so big that the cost of creating and destroying the thread is not significant.
Your second example makes no sense though because it creates a thread pool just to execute one Runnable. Creating a thread pool for one Runnable (or worse, for each new task) completely defeats the purpose of the thread-pool which is to re-use threads.
P.S.: If you are writing code that will become part of some larger system, and you are worried about the "right way" to create threads, then you probably should also learn what problem the java.util.concurrent.ThreadFactory interface was meant to solve.
Google is your friend.
According to documentation of ThreadPoolExecutor
Thread pools address two different problems: they usually provide
improved performance when executing large numbers of asynchronous
tasks, due to reduced per-task invocation overhead, and they provide a
means of bounding and managing the resources, including threads,
consumed when executing a collection of tasks. Each ThreadPoolExecutor
also maintains some basic statistics, such as the number of completed
tasks.
First approach is suitable for me if I want to spawn single background processing and for small applications.
I will prefer second approach for controlled thread execution environment. If I use ThreadPoolExecutor, I am sure that 1 thread will be running at time , even If I submit more threads to executor. Such cases are tend to happen if you consider large enterprise application, where threading logic is not exposed to other modules. In large enterprise application , you want to control the number of concurrent running threads. So second approach is more pereferable if you are designing enterprise or large scale applications.
I was wondering if there was a form of timer that I can use that doesn't pause all of my code Thread.sleep(ms) is not what I need because it pauses all of my code.
EDIT: Okay, I think I misworded that. Here's my edit:
Is there a way to measure a certain amount of time in Java without pausing my main method?
I like to using Executors class. It have a nice method that is newScheduledThreadPool. It gives you an ScheduledExecutorService instance, which have a lot of scheduling methods.
Check it out here here:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.schedule(threadToExecute, 10, TimeUnit.SECONDS);
This code will start threadToExecute thread after 10 seconds, without pausing your main thread.
Depends on which Frameworks you use. A pretty generic way would be to start a new Thread, pause that Thread via Thread.sleep(ms) and then do whatever you want to do after that delay, but of course that requires a little bit of care because of concurrency issues.
You might want to look into the Timer class. You can attach it to a thread, schedule events, and add delays. What you could do with this is you could create a thread to run along side your main thread and have it run from there. Because they will be on two completely different threads, you don't need to worry about them interfering with each other. To run the other thread, you could create a class that extends Thread and run it. Then use the Timer(String name) constructor to create a Timer for the thread.
In my Android project I had a lot of places where I need to run some code asynchronously (a web request, call to db etc.). This is not long running tasks (maximum a few seconds).
Until now I was doing this kind of stuff with creating a new thread, passing it a new runnable with the task. But recently I have read an article about threads and concurrency in Java and understood that creating a new Thread for every single task is not a good decision.
So now I have created a ThreadPoolExecutor in my Application class which holds 5 threads.
Here is the code:
public class App extends Application {
private ThreadPoolExecutor mPool;
#Override
public void onCreate() {
super.onCreate();
mPool = (ThreadPoolExecutor)Executors.newFixedThreadPool(5);
}
}
And also I have a method to submit Runnable tasks to the executor:
public void submitRunnableTask(Runnable task){
if(!mPool.isShutdown() && mPool.getActiveCount() != mPool.getMaximumPoolSize()){
mPool.submit(task);
} else {
new Thread(task).start();
}
}
So when I want to run an asynchronous task in my code I get the instance of App and call the submitRunnableTask method passing the runnable to it. As you can see, I also check, if the thread pool has free threads to execute my task, if not, I create a new Thread (I don't think that this will happen, but in any case... I don't want my task to wait in a queue and slow down the app).
In the onTerminate callback method of Application I shutdown the pool.
So my question is the following: Is this kind of pattern better then creating new Threads in code? What pros and cons my new approach has? Can it cause problems that I am not aware off yet? Can you advice me something better than this to manage my asynchronous tasks?
P.S. I have some experience in Android and Java, but I am far from being a concurrency guru ) So may be there are aspects that I don't understand well in this kind of questions. Any advice will be appreciated.
This answer assumes your tasks are short
Is this kind of pattern better then creating new Threads in code?
It's better, but it's still far from ideal. You are still creating threads for short tasks. Instead you just need to create a different type of thread pool - for example by Executors.newScheduledThreadPool(int corePoolSize).
What's the difference in behaviour?
A FixedThreadPool will always have a set of threads to use and if all threads are busy, a new task will be put into a queue.
A (default) ScheduledThreadPool, as created by the Executors class, has a minimum thread pool that it keeps, even when idle. If all threads are busy when a new task comes in, it creates a new thread for it, and disposes of the thread 60 seconds after it is done, unless it's needed again.
The second one can allow you to not create new threads by yourself. This behaviour can be achieved without the "Scheduled" part, but you will then have to construct the executor yourself. The constructor is
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
The various options allow you to fine-tune the behaviour.
If some tasks are long...
And I mean long. As in most of your application lifetime (Realtime 2-way connection? Server port? Multicast listener?). In that case, putting your Runnable in an executor is detrimental - standard executors are not designed to cope with it, and their performance will deteriorate.
Think about your fixed thread pool - if you have 5 long-running tasks, then any new task will spawn a new thread, completely destroying any possible gains of the pool. If you use a more flexible executor - some threads will be shared, but not always.
The rule of thumb is
If it's a short task - use an executor.
If it's a long task - make sure your executor can handle it (i.e. it either doesn't have a max pool size, or enough max threads to deal with 1 more thread being gone for a while)
If it's a parallel process that needs to always run alongside your main thread - use another Thread.
To answer your question — Yes, using Executor is better than creating new threads because:
Executor provides a selection of different thread pools. It allows re-use of already existing threads which increases performance as thread creation is an expensive operation.
In case a thread dies, Executor can replace it with a new thread without affecting the application.
Changes to multi-threading policies are much easier, as only the Executor implementation needs to be changed.
Based on the comment of Ordous I have modified my code to work with only one pool.
public class App extends Application {
private ThreadPoolExecutor mPool;
#Override
public void onCreate() {
super.onCreate();
mPool = new ThreadPoolExecutor(5, Integer.MAX_VALUE, 1, TimeUnit.MINUTES, new SynchronousQueue<Runnable>());
}
}
public void submitRunnableTask(Runnable task){
if(!mPool.isShutdown() && mPool.getActiveCount() != mPool.getMaximumPoolSize()){
mPool.submit(task);
} else {
new Thread(task).start(); // Actually this should never happen, just in case...
}
}
So, I hope this can be useful to someone else, and if more experienced people have some comments on my approach, I will very appreciate their comments.
I try to work with Java's FutureTask, Future, Runnable, Callable and ExecutorService types.
What is the best practice to compose those building blocks?
Given that I have multiple FutureTasks and and I want to execute them in sequence.
Ofcourse I could make another FutureTask which is submitting / waiting for result for each subtask in sequence, but I want to avoid blocking calls.
Another option would be to let those subtasks invoke a callback when they complete, and schedule the next task in the callback. But going that route, how to I create a proper outer FutureTask object which also handles exceptions in the subtask without producing that much of a boilerplate?
Do I miss something here?
Very important thing, though usually not described in tutorials:
Runnables to be executed on an ExecutorService should not block. This is because each blocking switches off a working thread, and if ExecutorService has limited number of working threads, there is a risk to fall into deadlock (thread starvation), and if ExecutorService has unlimited number of working threads, then there is a risk to run out of memory. Blocking operations in the tasks simply destroy all advantages of ExecutorService, so use blocking operations on usual threads only.
FutureTask.get() is blocking operation, so can be used on ordinary threads and not from an ExecutorService task. That is, it cannot serve as a building block, but only to deliver result of execution to the master thread.
Right approach to build execution from tasks is to start next task when all input data for the next task is ready, so that the task do not have to block waiting for input data. So you need a kind of a gate which stores intermediate results and starts new task when all arguments have arrived. Thus tasks do not bother explicitly to start other tasks. So a gate, which consists of input sockets for arguments and a Runnable to compute them, can be considered as a right building block for computations on ExcutorServices.
This approach is called dataflow or workflow (if gates cannot be created dynamically).
Actor frameworks like Akka use this approach but are limited in the fact that an actor is a gate with single input socket.
I have written a true dataflow library published at https://github.com/rfqu/df4j.
I tried to do something similar with a ScheduledFuture, trying to cause a delay before things were displayed to the user. This is what I come up with, simply use the same ScheduledFuture for all your 'delays'. The code was:
public static final ScheduledExecutorService scheduler = Executors
.newScheduledThreadPool(1);
public ScheduledFuture delay = null;
delay = scheduler.schedule(new Runnable() {
#Override
public void run() {
//do something
}
}, 1000, TimeUnit.MILLISECONDS);
delay = scheduler.schedule(new Runnable() {
#Override
public void run() {
//do something else
}
}, 2000, TimeUnit.MILLISECONDS);
Hope this helps
Andy
The usual approach is to:
Decide about ExecutorService (which type, how many threads).
Decide about the task queue (for how long it could be non-blocking).
If you have some external code that waits for the task result:
* Submit tasks as Callables (this is non blocking as long as you do not run out of the queue).
* Call get on the Future.
If you want some actions to be taken automatically after the task is finished:
You can submit as Callables or Runnables.
Just add that you need to do at the end as the last code inside the task. Use
Activity.runOnUIThread these final actions need to modify GUI.
Normally, you should not actively check when you can submit one more task or schedule callback in order just to submit them. The thread queue (blocking, if preferred) will handle this for you.
I have a requirement to start a task..Now many threads can start this task and this task normally takes 4-5 seconds to complete. I want to prevent the starting of a task if this task has been already started by some other thread.
In order to implement this requirement, I am thinking of starting a timer or stopwatch in a different thread whenever the task is started by some thread. Now when the timer times out after a configured time-interval, another thread can starts a task.
So, is starting a timer or stopwatch in a different thread to see if the particular time has been reached is a good solution?Is there any good alternative for it?
If I understand correctly, this is a bad idea. Basically you are assumming your job will never run for more than 5 seconds so if the watch tells you that some job was started less than 5 seconds ago, you won't start another one. This is very unreliable.
Instead create some sort of flag that you set when job starts and unset when ends. AtomicBoolean is perfect for that:
private AtomicBoolean flag = new AtomicBoolean();
//...
if(!flag.getAndSet(true)) {
try {
//do your work
} finally {
flag.set(false);
}
} else {
//Already running
}
If you want another job to wait for the previous one instead of simply being discarded, just surround your task with synchronized or use some different locking mechanism.
Note: if your jobs are distributed you will need a distributed locking mechanism, like a databasse or hazelcast.
If you are trying to do this in java then you can consider using a synchronized block on the Object Oriented approach on JAVA.
So any task that you want to make sure is done by one thread at a time then make a class and a synchronized method in that class, also make sure you all the threads share the same object of the class and call this method in which they want to perform the task.
For Example
Class SyncTask{
synchronized void task1(){
//Perform your task here
}
}
Create the object of this class once during the lifetime of your application and then use this same object across all the threads and let them call this method to which you want to perform your task.
In the case of multiple threads invoking this method at the same time. JVM will take care of the sequence and if one thread is already performing a task, the others calling it will wait for the first one to finish.
In this way you will be sure that only on thread is performing the task at any given time.
I hope this helps.
If you want to schedule task the framework of choice is usually something similar to Quartz. It should allow you to do what you need and more. Regarding the issue of non running concurrent tasks, I would recommend you take a look at this previous SO post which should point you in the right direction.