I have the following piece of code, I have a large loop that I want to run in parallel. Unfortunately a race condition exists, in some cases (not all, not predictable) I get blocked at s.awaitTermination. There is no thread synchronization except at the end where I remove the finished thread from the set, and if the set is empty call shutdown. Where am I going wrong? FYI thousands of tasks get added to the queue, I don't want them all trying to run at once, is there a better pattern than this?
When I check the queue, it has tasks left, and the pool threads are "parked at unsafe...." according to Netbeans debug.
EDIT: updating Thread to Runnable as suggested - did not fix the problem
ExecutorService s = Executors.newFixedThreadPool(8);
final Set<Runnable> threads = new HashSet<>();
for(/*lots of loops*/){
Runnable t = new Runnable(){
public void run(){
//some long task...
synchronized(threads){
threads.remove(this);
if(threads.isEmpty()){
s.shutdown();
}
}
}
}
}
synchronized(threads){
for(Runnable t : threads){
s.submit(t);
}
}
s.awaitTermination(1000, TimeUnit.SECONDS);
This is not is a solution for your question, but it might help you to do the same task easily. Take a look at the ExecutorCompletionService it can execute multiple tasks and it will return you a future that you can use to wait. Internally it uses a queue for the completed tasks so basically accomplished what you are trying to do here.
Related
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
I have a requirement in multi-threaded environment in java. The problem is like;
I have suppose 10 different task, and I want to assign all these 10 task to 10 different threads. Now the finish time for these tasks could be different. And there is some finishing or clearance task which should be performed when all these 10 threads are finished. In other words i need to wait until all threads are finished and then only I can go ahead with my further code execution.
Please let me know if any more details required here.
Thansk,
Ashish
Sounds like an ideal job for CountDownLatch.
Initialize it with 10 counts and when each thread finishes its job, it counts down one.
When all 10 threads have finished, the CountDownLatch will let the original thread run, and it can perform the cleanup.
And fire up an ExecutorService with 10 fixed threads to run the tasks.
CyclicBarier (JDK java.util.concurrent) of size 10 is perfect solutuon for you. With CyclicBarier you can wait for 10 threads. If all t hreads achieve barier then you can go further.
Edit: CyclicBarier is almost the same as CountDownLatch but you can reuse barier invoking reset() method.
Whilst CountDownLatch and CyclicBarier do the job of synchronizing multiple threads and performing one action when all threads reach the required point, they require all tasks to actively use this feature. If you are interested in the finishing of the entire task(s) only, the solution can be much simpler: add all tasks to a Collection and use the invokeAll method of an ExecutorService which returns when all tasks have been completed. A simple example:
Callable<Void> simpleTask=new Callable<Void>() {
public Void call() {
System.out.println("Performing one job");
return null;
}
};
List<Callable<Void>> list = Collections.nCopies(10, simpleTask);
ExecutorService es=Executors.newFixedThreadPool(10);
es.invokeAll(list);
System.out.println("All completed");
If each thread terminates after it is finished, you could just use the join() statement. A simple example can be found in the Essential Java Tutorials.
ArrayList<Thread> myThreads = new ArrayList<Thread>();
for (int i = 0; i < 10; i++){
//MyTaskRunnable is a Runnable with your logic
Thread t = new Thread(new MyTaskRunnable());
myThreads.add(t);
}
for(Thread t : myThreads){
t.start();
}
//here all threads are running
for(Thread t : myThreads){
t.join();
}
//here all threads have terminated
Edit:
The other answers all have their merits and are very useful in practice, the join() is however the most basic of the constructs. The CyclicBarrier and CountDownLatch versions allow your threads to continue running after reaching the synchronization point, which can be necessary in some cases. The ExecutorService is more suited to many tasks needing to be executed on a fixed number of threads (aka a thread pool), to create an ExecutorService for just 10 tasks is a bit drastic.
Finally, if you are new to learning Java or are taking a course on concurrency, you should try out all the variants and see what they do. The join is the most basic of these constructs and will help you understand you what is going on. Also it is the basic model supported by most other languages.
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 a scientific application which I usually run in parallel with xargs, but this scheme incurs repeated JVM start costs and neglects cached file I/O and the JIT compiler. I've already adapted the code to use a thread pool, but I'm stuck on how to save my output.
The program (i.e. one thread of the new program) reads two files, does some processing and then prints the result to standard output. Currently, I've dealt with output by having each thread add its result string to a BlockingQueue. Another thread takes from the queue and writes to a file, as long as a Boolean flag is true. Then I awaitTermination and set the flag to false, triggering the file to close and the program to exit.
My solution seems a little kludgey; what is the simplest and best way to accomplish this?
How should I write primary result data from many threads to a single file?
The answer doesn't need to be Java-specific if it is, for example, a broadly applicable method.
Update
I'm using "STOP" as the poison pill.
while (true) {
String line = queue.take();
if (line.equals("STOP")) {
break;
} else {
output.write(line);
}
}
output.close();
I manually start the queue-consuming thread, then add the jobs to the thread pool, wait for the jobs to finish and finally poison the queue and join the consumer thread.
That's really the way you want to do it, have the threads put their output to the queue and then have the writer exhaust it.
The only thing you might want to do to make things a little cleaner is rather than checking a flag, simply put an "all done" token on to the queue that the writer can use to know that it's finished. That way there's no out of band signaling necessary.
That's trivial to do, you can use an well known string, an enum, or simply a shared object.
You could use an ExecutorService.
Submit a Callable that would perform the task and return the string after completion.
When Submitting the Callable you get hold of a Future, store these references e.g. in a List.
Then simply iterate through the Futures and get the Strings by calling Future#get.
This will block until the task is completed if it not yet is, otherwise return the value immediately.
Example:
ExecutorService exec = Executors.newFixedThreadPool(10);
List<Future<String>> tasks = new ArrayList<Future<String>>();
tasks.add(exec.submit(new Callable<String> {
public String call() {
//do stuff
return <yourString>;
}
}));
//and so on for the other tasks
for (Future<String> task : tasks) {
String result = task.get();
//write to output
}
Many threads processing, one thread writing and a message queue between them is a good strategy. The issue that just needs to be solved, is knowing when all work is finished. One way to do that is to count how many worker threads you started, and then after that count how many responses you got. Something like this pseudo code:
int workers = 0
for each work item {
workers++
start the item's worker in a separate thread
}
while workers > 0 {
take worker's response from a queue
write response to file
workers--
}
This approach also works if the workers can find more work items while they are executing. Just include any additional not-yet-processed work in the worker responses, and then increment the workers count and start workers threads as usual.
If each of the workers returns just one message, you can use Java's ExecutorService to execute Callable instances which return the result. ExecutorService's methods give access to Future instances from which you can get the result when the Callable has finished its work.
So you would first submit all the tasks to the ExecutorService and then loop over all the Futures and get their responses. That way you would write the responses in the order in which you check the futures, which can be different from the order in which they finish their work. If latency is not important, that shouldn't be a problem. Otherwise, a message queue (as mentioned above) might be more suitable.
It's not clear if your output file has some defined order or if you just dump your data there. I assume it has no order.
I don't see why you need an extra thread for writing to output. Just synchronized the method that writes to file and call it at the end of each thread.
If you have many threads writing to the same file the simplest thing to do is to write to that file in the task.
final PrintWriter out =
ExecutorService es =
for(int i=0;i<tasks;i++)
es.submit(new Runnable() {
public void run() {
performCalculations();
// so only one thread can write to the file at a time.
synchornized(out) {
writeResults(out);
}
}
});
es.shutdown();
es.awaitTermination(1, TimeUnit.HOUR);
out.close();
I am storing a bunch of threads objects in an arraylist. I want to be able to start these threads at random. Same thread can be started more than once. Before I start a thread object, I check on whether the thread is alive, and if they have either of NEW or TERMINATED status. This restriction because, I don't want to disturb the 'busy' threads. Now, for NEW threads, this works fine. But for TERMINATED thread, I get an exception.
When a thread ends, shouldn't it go back to being 'new'? Or are threads 'disposable' - like use once and done?
As it says in the documentation for Thread.start(), "It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution."
It is better for you to keep hold of Runnable instances and implement your own logic for keeping track of when the execution of each one of them finishes. Using an Executor is probably the simplest way to run the Runnables.
You should probably be using the awesome stuff provided in java.util.concurrent. Based on your description, ThreadPoolExecutor sounds like a good thing to check out.
This is the way I did it
class GarbageDisposalThread extends Thread {
public void start() {
try {
super.start();
} catch( IllegalThreadStateException e ) {
this.arrayList.remove(this);
this.arrayList.add( new GarbageDisposalThread( this.arrayList ));
}
}
private GarbageDisposalThread() {
}
public GarbageDisposalThread( ArrayList<Whatever> arrayList ) {
this.arrayList = arrayList;
this.start();
}
public void run() {
// whatever the code
}
private ArrayList<Whatever> arrayList = null;
}
that's it!
you can change the code according to your needs :P
Java threads cannot be restarted.
From the javadoc:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
See the Thread.start() javadoc for more information.
There are other ways to accomplish what you are trying to do. For example, you could use new Threads that continue the work that was done in the Thread that has finished execution. You may also want to investigate the java.util.concurrent package.
From another post...
You could use ThreadPoolExecutor, which would allow you to pass in tasks and let the service assign a thread to a task. When the task is finished, the thread goes idle until it gets the next task.
So, you don't restart a thread, but you would redo/resume a task.