I have an object that I need to run through 4 scenarios. I want to split this between 2 threads (so I can send to an additional server)
I got this working to the 2 servers, but in trying to clean up the code i have created what looks like this;
ExecutorService executor1 = Executors.newFixedThreadPool(1);
ExecutorService executor2 = Executors.newFixedThreadPool(1);
executor1.execute(userProvisioner1);
executor1.execute(userProvisioner2);
executor2.execute(userProvisioner3);
executor2.execute(userProvisioner4);
executor1.shutdown();
executor2.shutdown();
while (!executor1.isTerminated()&!executor2.isTerminated()) {
}
userProvisioner1 & userProvisioner2 need to be run sequentially (as do 3 & 4) but can be run along side each other.
This does work, but I have hit issues since trying to use the 2 pools at once. Is this an issue with the pools or something else?
If you need sequential activity, you can call one task and then another. The simple solution in your case is something like this.
ExecutorService exec = Executors.newFixedThreadPool(2);
exec.execute(new Runnable() {
public void run() {
userProvisioner1.run();
userProvisioner2.run();
}
});
exec.execute(new Runnable() {
public void run() {
userProvisioner3.run();
userProvisioner4.run();
}
});
exec.shutdown();
exec.awaitTermination();
Related
Have the following, rather trivial intention in an JFX application: When a key is pressed on the keyboard and thus a handle(event ev) method is called, I want that something happens in a different, otherwise unused thread.
So far I found to have three options:
Either creating the new thread directly in the handle:
public void handle(KeyEvent ke)
{
new Thread(() -> {
// THE CODE
}).start();
}
}
Or I launch a different thread at programm start looking about like this:
public void run()
{
while(true)
{
if (triggered)
{
// THE CODE
}
}
}
and then in the handle() method, I just set the "triggered" field to true.
The third method would be to create as many instances of a class extending "Thread" as needed to be executed in parallel and use their start() function in the handle().
Well, from what I see, the former method has a significant overhead due to thread creation.
The second method is pointlessly requiring CPU resources 99.9% of the time.
That can only be weakened by adding a sleep() to the loop.
And the third method appears to be quite similar to the first as most resources are allocated when called start(), or am I wrong?
That method also has the downside to have to keep several instances in memmory because I can not preddict how many will be called in parallel.
What solution would you suggest?
Are there other possibilities?
Huge thanks in advance!
I suggest adding the task to an ExecutorService This works as a background thread pool and is idle when not used. The threads in it are reused however to improve efficiency. You can use a cached thread pool if you don't know how many threads at once you will need.
static final ExecutorService executor = Executors.newCachedThreadPool();
public void handle(KeyEvent ke)
{
executor.execute(() -> {
// THE CODE
});
}
or
public void handle(KeyEvent ke)
{
executor.execute(this::task1);
}
void task1()
{
// THE CODE
}
You can use a ThreadPoolExecutor, so you can avoid:
repeatly creating new thread
unnecessarily check triggered status
Like this:
ExecutorService executor = executors.newcachedthreadpool();
public void handle(KeyEvent ke)
{
Runnable runnable = new Runnable() {
void run() {
// code
}
}
executor.execute(runnable);
}
You could either use a JavaFX Service (https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Service.html) or create a Task (https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html) that you submit manually with a new Thread or using an Executor, for example from Executors.newCachedThreadPool().
The alternatives are covered quite well in https://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm.
Based on what you have written I would probably go for the Service, but both alternatives should work.
I have a two functions, one is the master and the other is the slave. Via master function I'm trying to learn behaviour of the other function. But I should do whatever calculation is a setted time interval. In this part, how can I set a timer, which is marked a boolean variable if timeout occur, and learn whether timeout occurs ?
func1 -----send message------> func2
start timer
if timeout occur, do something else
You can execute func2 in another Thread and let your original Thread join() with a specified timeout.
Of course you will need to take care of proper synchronization.
Simple example (left out InteruptedException handling)
void func1(){
Thread slave = new Thread(new Runnable(){
public void run(){
func2();
}
});
slave.start();
slave.join(100); // waits 100 milliseconds for slave to complete
if(!slave.isAlive()){
//slave completed its task
}else{
//slave not done yet, do something else
somethingElse();
}
}
Use the concurrent constructs in the JDK. In this case an ExecutorService and a CountDownLatch is a perfect match:
ExecutorService executor = Executors.newCachedThreadPool();
final CountDownLatch ready = new CountDownLatch(1);
executor.execute(new Runnable() {
#Override
public void run() {
// do something here
System.out.println("working ...");
ready.countDown();
}
});
boolean timeout = !ready.await(1, TimeUnit.MILLISECONDS);
if (timeout) {
doSomethingElse();
}
So I have code similar to this
synchronized(objectOne){ do stuff }
synchronized(objectTwo){ do stuff }
The problem with this is the program will wait for the lock on objectOne, even if the lock for objectTwo is available. What I'm trying to do is say: try to lock both objectOne and objectTwo, and whichever lock you get first do the stuff for that lock. I've come up with a solution but I think it's rather hacky and I'm wondering if anybody has any better ideas.
Here's my idea: Start 2 threads, each one waiting on a lock and then the main thread will wait on a CountDownLatch. So you end up with something like this:
CountDownLatch latch = new CountDownLatch(2);
new Thread(new Runnable(){
public void run(){
synchronized(objectOne) { do stuff }
latch.countDown();
}).start();
new Thread(new Runnable(){
public void run(){
synchronized(objectTwo) { do stuff }
latch.countDown();
}).start();
latch.await();
I think you should use Lock which provides you with the method boolean tryLock().
Returns:
true if the lock was acquired and false otherwise
Proceed with do stuff when you have at least one of the locks.
You might want to have 2 queues of jobs, 2 threads each polling a queue and execute the jobs.
For jobs related to objectOne, you put it in queue#1; jobs related to objectTwo in queue#2.
worker1.queue.put( new Runnable(){ public void run() { do stuff } } );
worker2.queue.put( new Runnable(){ public void run() { do stuff } } );
----
class Worker extends Thread
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
public void run()
while(true)
queue.take().run();
Depending on the amount of stuff it could be more overhead to spin off multiple threads to do stuff. It might just be best to do stuff in a single thread if stuff is a fast enough operation. You will have to time it to know.
I kind of like your hack, at least if it's a one-off situation. That said...
If you're doing this sort of thing a lot and want something "less hacky", I'd suggest ExecutorService#invokeAll(). This takes a list of Callables, executes them on a thread pool and blocks until they're all done.
Sketch:
ExecutorService es = Executors.newCachedThreadPool(); // for example...
List<Future<Void>> results = es.invokeAll(new ArrayList {{
add(new Callable<Void> {
public Void call() { synchronized(objectOne) { do stuff } }
});
add(new Callable<Void> {
public Void call() { synchronized(objectTwo) { do stuff } }
});
}});
// both Callables are done when you get here
This obviously assumes that it's ok to call these methods from different threads at this point in your app. If for some reason you need to call both from the same thread, I think you're doomed to use tryLock and busy-wait as discussed in Bhesh Gurung's answer.
I have a scenario where I use threads.
Firstly I have a folder where there are files which get updated frequently.
So, I wrote a thread which reads the contents of the folder and writes the file names to a static list and updates the list if new files come in.
Secondly i wrote another thread which takes the file names from the list and do some processing with the files.
These two threads run continuously, one checking for new files, one processing the new files.
Now I need to process three files at a time with three threads running. When one thread completes processing another thread takes another file name from the list and starts the process.
So I need some mechanism to have three threads and checking them whether they are alive or not and accordingly starts a new thread and the file list also gets updated frequently.
I also looked into ExecutorService but while the list get updated I could not provide it updated list.
Thanks,
Sandeep
Building on the existing answers, your code would look something like:
final ExecutorService executor = Executors.newFixedThreadPool(2);
final FilePoller poller = ...
final FileProcessor processor = ...
new Thread(new Runnable()
{
#Override
public void run()
{
while (true)
{
final File file = poller.pollForFile();
executor.submit(new Runnable() { public void run() { processor.processFile(file); } } );
}
}
});
Assuming your processors can keep up with the poller this would be fine, otherwise you'd want to put in some throttling mechanism before submitting to the executor.
Don't use a list; instead use a java.util.concurrent.ThreadPoolExecutor and just drop Runnable's representing the file to be processed into the executor instead of putting them into your global list.
Similar to #SimonC's suggestion but instead of a really long comment I have an answer.
final FilePoller poller = ...
final FileProcessor processor = ...
final ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(new Runnable() {
public void run() {
final File file = poller.pollForFile();
executor.submit(new Runnable() { public void run() { processor.processFile(file); } } );
// repeat, but wait for a free thread.
executor.submit(this);
}
});
// to stop the whole thing
executor.shutdown();
How about watching for changes in the folder and spawn a thread/file, assuming that the notification change is giving you a list of changes in the folder?
say I'm using a
ExecutorService ex = Executors.newFixedThreadPool(nrofthreads);
spinning up some work and waiting when it's done.
However I have same Threadlocal objects in the worker-threads which need to be closed when the batch is done.
Therefore, I would like to be able to call a custom close-method on all worker-threads created by the threadpool.
What would be the most elegant way to do that?
Right now as a hack I'm using:
for(int i =0 ; i<20; i++){ //make sure to touch all threads with 20 runs..
ex.execute(new Runnable(){
public void run(){
tearDownThreadLocals();
}
});
}
ex.shutdown();
but that doesn't look particulary robust to me ;-)
Thanks
GJ
You can use Executors.newFixedThreadPool(int, ThreadFactory) to pass a ThreadFactory, something like this:
ExecutorService ex = Executors.newFixedThreadPool(nrofthreads,
new ThreadFactory() {
public Thread newThread(final Runnable r) {
return new Thread(new Runnable() {
public void run() {
try {
r.run();
} finally {
tearDownThreadLocals();
}
}
});
}
});
EDIT: Just noticed that Executors already has a method that accepts a ThreadFactory, so no need to create ThreadPoolExecutor explicitly.