Is there a better way to use a CountUpDownLatch than Await? - java

I'm using a count up/down latch to keep a program limited to 6 threads, it works but what I really want is to always have 6 threads running. So that when one thread dies, another one starts up. With the implementation below, it only creates 6 new threads at a time, whenever the timeout expires.
Any suggestions on how to struct my loop to accomplish this?
int numThreads = 6;
CountUpDownLatch threadCounter = new CountUpDownLatch();
for(int t = 1; t <= numThreads; t++) {
while(list.hasNext()) {
new Thread(new ThreadController("processData",list.next())).start();
threadCounter.countUp();
}
try {
threadCounter.await(5, TimeUnit.MINUTES);
} catch (InterruptedException e) { e.printStackTrace(); }
}

Use an executor service which contains 6 threads like so,
ExecutorService exec = Executors.newFixedThreadPool(6);
for (int i = 0; i < 10; i++) {
exec.submit(() -> System.out.println("Hello"));
}
exec.shutdown();
You can either pass a Runnable or a Callable to the submit method of the ExecutorService. Here I have passed a lambda function as a Runnable which is valid starting from Java8. In your case you may do it like so,
exec.submit(new ThreadController("processData",list.next()));

Related

java multiple threads running , stop threads when one thread finds solution

I'm having troubles trying to stop my program that has multiple threads running, all threads running are trying to find the same solution but once one thread finds the solution all other threads are to stop.
In the main method I have created a thread group and add threads to it using a for loop and start them
ThreadGroup tg = new ThreadGroup("thread group");
Thread th;
for(int i = 0; i<4; i++){
th = new Thread(tg, new Runnable(), "Thread " + i)
th.start();
}
in the class that implements Runnable I am having troubles trying to figure out how to make it so that once one of the thread finds a solution all the threads will stop. What ends up happening is that either the other threads keep running and sometimes the threads will interupt each other and write over each other.
You have to interrupt those thread (and handle interruption in the runnable). I also not sure if you should use ThreadGroup - I remember seeing a Sonar warning about them.
You would perhaps better have to an ExecutorService and do that using a CountDownLatch (that's one way to do that):
ExecutorService es = Executors.newFixedThreadPool(100);
CountDownLatch cdl = new CountDownLatch(1);
for (int i = 0; i < 100; ++i) {
es.submit(() -> {
Thread.sleep(TimeUnit.SECONDS.toMillis(30)); // + exception handling
cdl.countDown();
});
}
cdl.await(); // or await(5, TimeUnit.MINUTES);
es.shutdownNow();
The trick is:
You create an ExecutorService with a pool of 100 threads.
You create a CoundDownLatch - a barrier - with a count of 1.
You submit your task which, when their job is done, invoke cdl.countDown(); reducing the counter from 1 to 0.
The parent thread wait for the CountDownLatch to reduce to 0 - you should probably use the second version (to block until 5 minutes for example).
If all Runnable fails, you won't have a result: either use a maximum await time, either you could add another CountDownLatch, this time with a count of 100 (the number of threads), countDown() in a try/finally, and in another thread, interrupt the one awaiting on the cdl. You could also do that in a loop:
CountDownLatch allCdl = new CountDownLatch(100);
for (;allCdl.getCount() != 0;) {
if (!cdl.await(60, TimeUnit.SECONDS)) {
if (allCdl.getCount() == 0) {
break;
}
}
}
However, the javadoc of getCount() mention that This method is typically used for debugging and testing purposes. (see CyclicBarrier). Not sure if this is the correct usage.
Upon realizing that a solution has been found, the victorious thread should signal the parent – which then signals all other children to stop, or simply kills them.
ThreadGroup tg = new ThreadGroup("thread group");
CountDownLatch latch = new CountDownLatch(1);
AtomicInteger result = new AtomicInteger();
Random random = new Random();
for (int i = 0; i < 4; i++) {
Thread th = new Thread(tg, () -> {
try {
Thread.sleep(random.nextInt(10000));
result.set(42);
latch.countDown();
System.out.println(Thread.currentThread().getName() + " completed task first");
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " was interrupted before it could finish the task");
}
}, "Thread " + i);
th.start();
}
while (latch.getCount() > 0) {
try {
latch.await();
} catch (InterruptedException ignored) {
}
}
tg.interrupt();
System.out.println("The result is " + result.get());
This example shows how to wait until a thread finishes.
You need to make sure your action is interruptible. Thread.sleep as shown in this example is interrubtible by default. See oracle docs for more info.
Also note that it is impossible to guarantee that all other threads will be interrupted before they complete. If you need to make sure to handle only one result, synchronize the access to your result variable and discard any changes beyond the first.

Java parallel tasks , only executing once

This code I have is not executing tasks in parallel,
it only executes the code in this case once (whatever is in the for loop, but it should be 2) :
public class mqDirect {
public static void main(String args[]) throws Exception {
int parallelism = 2;
ExecutorService executorService =
Executors.newFixedThreadPool(parallelism);
Semaphore semaphore = new Semaphore(parallelism);
for (int i = 0; i < 1; i++) {
try {
semaphore.acquire();
// snip ... do stuff..
semaphore.release();
} catch (Throwable throwable) {
semaphore.release();
}
executorService.shutdownNow();
}
}
}
In Java the main way to make code work in parallel is to create a Thread with a new Runnable as a constructor parameter. You then need to start it.
There are many tutorials to help you get this to happen properly.
As your code stands you are merely creating an ExecutorService (and not using it), creating a Semaphore (which should be done in the thread but isn't), performing some process and then shutting down the Executor.
BTW: ShutDownNow is probably not what you want, you should just use ShutDown.
OK, So I found this good tutorial
http://programmingexamples.wikidot.com/threadpoolexecutor
And I have done something like
public class mqDirect {
int poolSize = 2;
int maxPoolSize = 2;
long keepAliveTime = 10;
ThreadPoolExecutor threadPool = null;
final ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(
5);
public mqDirect()
{
threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize,
keepAliveTime, TimeUnit.SECONDS, queue);
}
public void runTask(Runnable task)
{
threadPool.execute(task);
System.out.println("Task count.." + queue.size());
}
public void shutDown()
{
threadPool.shutdown();
}
public static void main (String args[]) throws Exception
{
mqDirect mtpe = new mqDirect();
// start first one
mtpe.runTask(new Runnable()
{
public void run()
{
for (int i = 0; i < 2; i++)
{
try
{
System.out.println("First Task");
runMqTests();
Thread.sleep(1000);
} catch (InterruptedException ie)
{
}
}
}
});
// start second one
/*
* try{ Thread.sleep(500); }catch(InterruptedException
* ie){}
*/
mtpe.runTask(new Runnable()
{
public void run()
{
for (int i = 0; i < 2; i++)
{
try
{
System.out.println("Second Task");
runMqTests();
Thread.sleep(1000);
} catch (InterruptedException ie)
{
}
}
}
});
mtpe.shutDown();
// runMqTests();
}
And it works !
But the problem is , this duplicated code ... runMqtests() is the same task, is there a way to specify it to run in parallel without duplicating the code?
The example I based this off is assuming each task is different.
This code I have is not executing tasks in parallel, it only executes the code in this case once (whatever is in the for loop, but it should be 2) :
Just because you instantiate an ExecutorService instance doesn't mean that things magically run in parallel. You actually need to use that object aside from just shutting it down.
If you want the stuff in the loop to run in the threads in the service then you need to do something like:
int parallelism = 2;
ExecutorService executorService = Executors.newFixedThreadPool(parallelism);
for (int i = 0; i < parallelism; i++) {
executorService.submit(() -> {
// the code you want to be run by the threads in the exector-service
// ...
});
}
// once you have submitted all of the jobs, you can shut it down
executorService.shutdown();
// you might want to call executorService.awaitTermination(...) here
It is important to note that this will run your code in the service but there are no guarantees that it will be run "in parallel". This depends on your number of processors and the race conditions inherent with threads. For example, the first task might start up, run, and finish its code before the 2nd one starts. That's the nature of threaded programs which are by design asynchronous.
If, however, you have at least 2 cores, and the code that you submit to be run by the executor-service takes a long time to run then most likely they will be running at the same time at some point.
Lastly, as #OldCurmudgeon points out, you should call shutdown() on the service which allows current jobs already submitted to the service to run as opposed to shutdownNow() which cancels and queued jobs and also calls thread.interrupt() on any running jobs.
Hope this helps.

main thread consumer and other threads producer

My questions is, I have a data set of 1000 records. I want 3 threads that process the data like this,
thread1 from record 1 to 300, thread2 from 301 to 600 and so on. One thread can make a request and fetch 50 records at a time, create an object and put it in a queue.
Main thread will simultaneously read data from the queue.
Below is the code, the problem I am facing is that recordRead variable tells the starting point from where the thread should start reading the records.
But how can I set different value for each thread e.g for thread1 it should be 0 and recordsToRead should be 300 and for thread2, recordRead should be 300 and recordsToRead to be 300+300=600 and for last thread it should be 600 and upto the end.
pagesize=50
pagesize,recordRead and recordToRead are all variables that belong to main class and main thread.
ExecutorService service = Executors.newFixedThreadPool(nThreads);
while(nThreads > 0) {
nThreads--;
service.execute(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
do {
int respCode = 0;
int RecordsToRead = div;
JSONObject jsObj = new JSONObject();
jsObj.put("pagesize", pageSize);
jsObj.put("start", recordsRead);
jsObj.put("searchinternalid", searchInternalId);
try {
boolean status = req.invoke(jsObj);
respCode = req.getResponseCode();
} catch (Exception e) {
req.reset();
e.printStackTrace();
return true;
}
JSONObject jsResp = req.getResponseJson();
//here jsResp will be added to ArrayBlockingQueue.
req.reset();
}while(!isError && !isMaxLimit && recordsRead < RecordsToRead);
}
});
}
After this loop will be the code of main thread reading the queue.
how can I set recordsRead and recordToread for all threads.
And how to make main thread wait untill atleast one thread inserts an object in queue.
I see in you definition two problems. First problem is to perform parallel chunk computation and second one is to create a continous pipeline from this. Lets start from the first problem. To make parallel computations with predefined size the best option fmpv will be to use fork-join framework. Not only by performance (work stealing is really effective) but also due to simpler code. But since you are limited to 3 threads for me it also seems valid to use threads directly. Simply what you want can me implemented by this way:
final int chunkSize = 300;
//you can also use total amount of job
//int totalWork = 1000 and chunk size equals totalWork/threadsNumber
final int threadsNumber = 3;
Thread[] threads = new Thread[threadsNumber];
for (int ii = 0; ii < threadsNumber; ii++) {
final int i = ii;
threads[ii] = new Thread(() -> {
//count your variable according the volume
// for example you can do so
int chunkStart = i * chunkSize;
int chunkEnd = chunkStart + chunkSize;
for(int j = chunkStart; j < chunkEnd; j++) {
//object creation with necessary proprs
//offer to queue here
}
});
threads[ii].start();
}
//your code here
//take here
for (int ii = 0; ii < threadsNumber; ii++) {
try {
//this part is only as example
//you do not need it
//here if you want you can also w8 for completion of all threads
threads[ii].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Now about the second problem with consuming. For this puprose you can use for example ConcurrentLinkedBlockingQueue (http://www.jgroups.org/javadoc/org/jgroups/util/ConcurrentLinkedBlockingQueue.html). Make offer in producer threads and use take method in main.
But to be honest i still did not get the reason of your problem. Do you want to create continuous pipeline or it is just one-time computation?
Also i will recommend you to take this course: https://www.coursera.org/learn/parallel-programming-in-java/home/welcome.
This will help you exactly with your problem and provide various solutions. There are also concurrent and distributed computing courses.

Asynchronous process on Executor Service

I am using executor service for multi threading. Spanned across 15 threads, current process does completes 15 threads before moving on to next executor services which is again spanned across 15 threads. I am looking for code help where if any of current threads in step 1 executor services completes processing, i need to move on to next executor services which can start using the threads instead of waiting on completion of 15 threads in step 1 to complete.
I want to utilize the threads completed and move on to step 2 even if other threads are getting executed in step1 and as soon as each thread in step 1 gets completed, step 2 can grab and continue processing. Suggestions pls
// Step 1
ExecutorService executor1 = Executors.newFixedThreadPool(15);
for (int i=0;i<=15;i++) {
Runnable worker = new Runnable("Step 1 Insert");
executor1.execute(worker); }
executor1.shutdown();
// Step 2
ExecutorService executor2 = Executors.newFixedThreadPool(15);
for (int i=0;i<=15;i++) {
Runnable worker = new Runnable("Step 2 Insert");
executor2.execute(worker); }
executor2.shutdown();
Why can't you just do all the steps in the same Runnable?
e.g.
ExecutorService executor = Executors.newFixedThreadPool(15);
for (int i=0;i<=15;i++) {
Runnable worker = new Runnable() {
public void run() {
doStep1();
doStep2();
doStep3();
...
}
};
executor.execute(worker);
}
executor.shutdown();
#SpiderPig's answer is one good solution IMHO, yet I would like to give an alternative in case you want to decouple steps:
Use one single Executor, in your case the requirement seems to be a FixedThreadPool with 15 Threads.
Next would be to define Step-Runnables like so:
class StepX implements Runnable{
private final State _state; // Reference to the data to work on.
StepX( State state ){
_state = state;
}
public void run(){
// work on _state
executor.submit( new StepXplusOne( _state ) ); // reference executor in outer class and schedule next step.
}
}
You can see that I used a State object, which holds all data you need to perform the steps and collect the result.
Of course you'd need to define StepX as Step1, Step2, ...
In the outer class, you'd only have to submit N Step1-Runnables and it will only use your 15 Threads and go through the steps.
I left out a means to signal when all steps are done, because there are plenty of possibilities to do this and I am sure you can pick one by yourself.
You can use ExecutorCompletionService. I slightly modified example from JavaDoc
ExecutorService executor1 = Executors.newFixedThreadPool(15);
ExecutorService executor2 = Executors.newFixedThreadPool(15);
....
CompletionService<Result> ecs = new ExecutorCompletionService<Result>(executor1);
for (Callable<Result> s : solvers)
ecs.submit(s);
int n = solvers.size();
for (int i = 0; i < n; ++i) {
Result r = ecs.take().get();
if (r != null)
executor2.submit(r);
}
executor1.shutdown();
//and shutdown executor2 when you don't need it
Result class is just for example and I assume it implements Callable or Runnable so it could be submitted into the second executor.
You can also init instance of ExecutorService as new ThreadPoolExecutor(0, 15, 10, TimeUnit.SECONDS, new LinkedBlockingQueue()) to terminate threads which are not needed right now, but you want to reuse this executor later.
Or you can simply use one executor. After receiving a completed task from ExecutorCompletionService resubmit it (or its result) into the same executor (Thanks #Fildor). But in this case you need to determine when task is completed first time.
for (int i = 0; i < n;) {
Result r = ecs.take().get();
if (r != null && isCompletedFirstTime(r))//some user defined function
executor1.submit(r);
else
++i;//we need to know when to stop, otherwise we'll stuck in `take()`
}
You can try use CountDownLatch class.
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.html
final CountDownLatch latch = new CountDownLatch(1);
ExecutorService executor1 = Executors.newFixedThreadPool(15);
for (int i = 0; i <= 15; i++) {
Runnable worker = new Runnable() {
#Override
public void run() {
latch.countDown();
}
};
executor1.execute(worker);
}
latch.await();
ExecutorService executor2 = Executors.newFixedThreadPool(15);
for (int i = 0; i <= 15; i++) {
Runnable worker = new Runnable("Step 2 Insert");
executor2.execute(worker);
}
executor2.shutdown();

ThreadPoolExecutor Utility methods

I am writing a thread pool utility in my multithreading program. i just need to validate the following methods are correct and are they return the right values for me. i am using a LinkedBlockingQueue with size of 1. and also I refer to the java doc and it always says 'method will return approximate' number phrase. so i doubt weather following conditions are correct.
public boolean isPoolIdle() {
return myThreadPool.getActiveCount() == 0;
}
public int getAcceptableTaskCount() {
//initially poolSize is 0 ( after pool executes something it started to change )
if (myThreadPool.getPoolSize() == 0) {
return myThreadPool.getCorePoolSize() - myThreadPool.getActiveCount();
}
return myThreadPool.getPoolSize() - myThreadPool.getActiveCount();
}
public boolean isPoolReadyToAcceptTasks(){
return myThreadPool.getActiveCount()<myThreadPool.getCorePoolSize();
}
Please let me know your thoughts and suggestions.
UPDATE
interesting thing was if pool returns me there are 3 threads available from the getAcceptableTaskCount method and when i pass 3 tasks to the pool some times one task got rejected and it is handle by RejectedExecutionHandler. some times pool will handle all the tasks i passed. i am wondering why pool is rejected the tasks since i am passing tasks according to the available thread count.
--------- implementation of the answer of gray---
class MyTask implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("exec");
}
}
#Test
public void testTPool(){
ExecutorService pool = Executors.newFixedThreadPool(5);
List<Future<MyTask>> list = new ArrayList<Future<MyTask>>();
for (int i = 0; i < 5; i++) {
MyTask t = new MyTask();
list.add(pool.submit(t, t));
}
for (int i = 0; i < list.size(); i++) {
Future<MyTask> t = list.get(i);
System.out.println("Result -"+t.isDone());
MyTask m = new MyTask();
list.add(pool.submit(m,m));
}
}
This will print Result -false in the console meaning that task is not complete.
From your comments:
i need to know that if pool is idle or pool can accept the tasks. if pool can accept, i need to know how much free threads in the pool. if it is 5 i will send 5 tasks to the pool to do the processing.
I don't think that you should be doing the pool accounting yourself. For your thread pool if you use Executors.newFixedThreadPool(5) then you can submit as many tasks as you want and it will only run them in 5 threads.
so i get the first most 5 tasks from the vector and assign them to the pool.ignore the other tasks in the vector since they may be update / remove from a separate cycle
Ok, I see. So you want to maximize parallelization while at the same time not pre-loading jobs? I would think that something like the following pseudo code would work:
int numThreads = 5;
ExecutorService threadPool = Executors.newFixedThreadPool(numThreads);
List<Future<MyJob>> futures = new ArrayList<Future<MyJob>>();
// submit the initial jobs
for (int i = 0; i < numThreads; i++) {
MyJob myJob = getNextBestJob();
futures.add(threadPool.submit(myJob, myJob));
}
// the list is growing so we use for i
for (int i = 0; i < futures.size(); i++) {
// wait for a job to finish
MyJob myJob = futures.get(i);
// process the job somehow
// get the next best job now that the previous one finished
MyJob nextJob = getNextBestJob();
if (nextJob != null) {
// submit the next job unless we are done
futures.add(threadPool.submit(myJob, myJob));
}
}
However, I don't quite understand how the thread count would change however. If you edit your question with some more details I can tweak my response.

Categories