ArrayBlockingQueue with Unique ID - java

After taking help from StackOverflow, I found the solution that I have implemented below.
Problem Statement:-
Each thread needs to use UNIQUE ID every time and it has to run for 60 minutes or more, So in that 60 minutes it is possible that all the ID's will get finished so I need to reuse those ID's again. So I am using ArrayBlockingQueue concept here.
Two Scenario:-
If the command.getDataCriteria() contains Previous then each thread
always needs to use UNIQUE ID between 1 and 1000 and release it for reusing
again.
Else if the command.getDataCriteria() contains New then each thread
always needs to use UNIQUE ID between 2000 and 3000 and release it for
reusing again.
Question:-
One weird thing that I have just noticed is- In the below else if loop if you see my below code in run method if the command.getDataCriteria() is Previous then also it gets entered in the else if block(which is for New) which shouldn't be happening right as I am doing a .equals check? Why this is happening?
else if(command.getDataCriteria().equals(PDSLnPConstants.DATA_CRITERIA_NEW)) {
Below is my code:-
class ThreadNewTask implements Runnable {
private Command command;
private BlockingQueue<Integer> existPool;
private BlockingQueue<Integer> newPool;
private int existId;
private int newId;
public ThreadNewTask(Command command, BlockingQueue<Integer> pool1, BlockingQueue<Integer> pool2) {
this.command = command;
this.existPool = pool1;
this.newPool = pool2;
}
public void run() {
if(command.getDataCriteria().equals(PDSLnPConstants.DATA_CRITERIA_PREVIOUS)) {
try {
existId = existPool.take();
someMethod(existId);
} catch (Exception e) {
System.out.println(e);
} finally {
existPool.offer(existId);
}
} else if(command.getDataCriteria().equals(PDSLnPConstants.DATA_CRITERIA_NEW)) {
try {
newId = newPool.take();
someMethod(newId);
} catch (Exception e) {
System.out.println(e);
} finally {
newPool.offer(newId);
}
}
}
// And this method needs to be synchronized or not?
private synchronized void someMethod(int i) {
System.out.println();
System.out.println("#####################");
System.out.println("Task ID: " +i);
System.out.println("#####################");
System.out.println();
}
}
public class TestingPool {
public static void main(String[] args) throws InterruptedException {
int size = 10;
int durationOfRun = 60;
LinkedList<Integer> availableExistingIds = new LinkedList<Integer>();
LinkedList<Integer> availableNewIds = new LinkedList<Integer>();
for (int i = 1; i <= 1000; i++) {
availableExistingIds.add(i);
}
for (int i = 2000; i <= 3000; i++) {
availableNewIds.add(i);
}
BlockingQueue<Integer> existIdPool = new ArrayBlockingQueue<Integer>(1000, false, availableExistingIds);
BlockingQueue<Integer> newIdPool = new ArrayBlockingQueue<Integer>(1000, false, availableNewIds);
// create thread pool with given size
ExecutorService service = new ThreadPoolExecutor(size, size, 500L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), new ThreadPoolExecutor.CallerRunsPolicy());
// queue some tasks
long startTime = System.currentTimeMillis();
long endTime = startTime + (durationOfRun * 60 * 1000L);
// Running it for 60 minutes
while(System.currentTimeMillis() <= endTime) {
Command nextCommand = getNextCommandToExecute();
service.submit(new ThreadNewTask(nextCommand, existIdPool, newIdPool));
}
// wait for termination
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
Update:-
One weird thing that I have just noticed is- In the below else if loop if the command is Previous then also it gets entered in the else if block which shouldn't be happening right? Why this is happening? I have no clue why this thing is happening?
else if(command.getDataCriteria().equals(PDSLnPConstants.DATA_CRITERIA_NEW)) {

There is no way if you enter an if () that you enter the else as well so something else is happening. I don't see anything wrong with your code so I suspect that you are misinterpreting your output. Are you expecting a different Command to come from getNextCommandToExecute()?
I just ran your code with a simulated Command which sets a random dataCriteria and got the following output. I see nothing wrong with it:
Task ID: 2001
Task ID: 1
Task ID: 2002
Task ID: 2003
Task ID: 2
Task ID: 2004
Task ID: 3
Task ID: 2005
...
Are you expecting some sort of specific timing for your threads? Given thread race conditions, the first Command produced is not necessarily the first output you will see.
Here is some general feedback on your code:
I would use pool.put(...) instead of offer(...) which could return false.
You might as well fill your queues after you construct them as opposed to loading them with a LinkedList.
You should use ArrayList instead of LinkedList usually.
You load in for (int i = 2000; i <= 3000; i++) but that needs to be from 2001 to 3000 else it will be more than 1000 numbers.

Related

How to ensure execution order of threads [duplicate]

This question already has answers here:
How threads are executed in the memory?
(2 answers)
Closed 2 years ago.
This is a simplified version of the problem. Given n number of threads, each printing a constant number all the time. For example, Thread-1 should always print 1, Thread-2 should always print 2 and so on...
How to ensure, the threads are executed in order i.e. the output should be as below:
Thread-1: 1
Thread-2: 2
Thread-3: 3
.
.
.
Thread-n: n
I have a naïve solution to do it through wait()/notify() but I guess there might be a better solution than that. Perhaps, using Semaphore maybe? I don't know.
Update:
Based on the answers received, I think I was not very clear. There are some constraints:
All threads should start at once (assume we don't really have control on that)
Once all the threads start, there should be some sort of communication between the threads to execute in order.
This sequentially execution of thread can be handled beautifully using Thread.join() method. To handle it properly, you may have to create MyRunnable(or, use any name you prefer) which implements Runnable interface. Inside MyRunnable, you can inject a parent Thread, and call parent.join() at top of MyRunnable.run() method. The code is given below:
public class SequentialThreadsTest {
static class MyRunnable implements Runnable {
static int objCount; // to keep count of sequential object
private int objNum;
private Thread parent; // keep track of parent thread
MyRunnable(Thread parent) {
this.parent = parent;
this.objNum = objCount + 1;
objCount += 1;
}
#Override
public void run() {
try {
if(parent != null) {
parent.join();
}
System.out.println("Thread-" + objNum + ": " + objNum);
} catch(InterruptedException e) {
e.printStackTrace();
// do something else
} finally {
// do what you need to do when thread execution is finished
}
}
}
public static void main(String[] args) {
int n = 10;
Thread parentThread = null;
for(int i=0; i<n; i++) {
Thread thread = new Thread(new MyRunnable(parentThread));
thread.start();
parentThread = thread;
}
}
}
And the output is:
Thread-1: 1
Thread-2: 2
Thread-3: 3
Thread-4: 4
Thread-5: 5
Thread-6: 6
Thread-7: 7
Thread-8: 8
Thread-9: 9
Thread-10: 10
You haven't specified many details, but if you only want serializable thread execution you can wait for previous thread to finish and then print. Something like this:
public static void main(String[] args) {
Thread thread = null;
for (int i = 0; i < 10; i++) {
int index = i;
Thread previousThread = thread;
thread = new Thread(() -> {
if (previousThread != null) {
try {
previousThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(index);
});
thread.start();
}
}
Try making a queue - this will do exactly what you want. Simply change the value of n to however many threads you have, and add all the threads sequentially (only once). If ever you want to stop the threads from executing, all you have to do is add end to the queue. Obviously, for a larger project, you will need to modify this code a little bit (I would recommend replacing the main method with a class initializer and pass the LinkedBlockingQueue as a pre-built argument)
import java.util.concurrent.LinkedBlockingQueue;
public class HelloWorld{
private static int n = 2;
private static LinkedBlockingQueue<Thread> queue = new LinkedBlockingQueue<>(n+1);
static Thread a = new Thread(()->{
System.out.print("a");
});
static Thread b = new Thread(()->{
System.out.print("b");
});
static Thread end = new Thread(()->{
break_ = true;
});
public static final int END = 20;//this and the counter are just here so the code doesn't run forever
public static volatile int i = 0;
public static volatile boolean break_ = false;
public static void main(String []args){
queue.add(a);
queue.add(b);
//queue.add(end);
outerloop:
while(true){
Thread toBeRun = queue.poll();
try{
toBeRun.run();
queue.add(toBeRun);
i++;
if(i>=END || break_){//i>=END does not need to be here, it's just to stop it from running forever in this example
break;
}
}catch(NullPointerException e){
break;
}
}
}
}
Note: This uses java 8 lambdas. If you're using an older version of java, you will need to create the threads using the run method.

Multi-threading and stopping a thread

I could really need some Help on my project.
Task :
The aim of the test is to create a π (Pi) calculation using various
Computation processes accelerated by multi-threading.
Use the BigDecimal class for better precision.
Use your own exception classes and pack all classes in one
neat package concept.
I tried to implement the Leibniz-method and my main issue was that i dont know how to stop a Thread from my main method while the Threads are running. My Teacher showed us and example of his mian method and you can clearly see that he is starting the method with for example 4 threads. And a few seconds later he is able to stop all of the threads.
Here is his example of the main class:
CalculatePi pi = new Leibniz();
System.out.println("Start: " + pi.getMethodName());
pi.startCalculation(4); //four threads
int prec = 0;
BigDecimal result = BigDecimal.ZERO;
long timeStart = System.currentTimeMillis();
while(prec < MAX_PRECISION) {
someDelay(); //give some time to calculate
BigDecimal newResult = pi.getValue();
int newPrec = precicion(result, newResult);
if(newPrec != prec) {
System.out.println("pi (" + newPrec + "): " + newResult);
prec = newPrec;
}
result = newResult;
}
long timeStop = System.currentTimeMillis();
pi.stopCalculation();
System.out.println( (timeStop - timeStart) + " ms");
System.out.println(pi.getInternalSteps() + " calulation steps");
Here are my first Ideas to Implement the task (dont get confused i mainly focus on the method "startCalculation(int numThreads)" and "stopCalculation()" which are both given by an interface)
// Methode soll Leibniz Verfahren mit mehreren Threads berechnen
#Override
public boolean startCalculation(int numThreads) {
// Threads müssen in Array gespeichert werden um damit zu arbeiten
LeibnizThread[] threadSpeicher = new LeibnizThread[numThreads];
for(int i = 0; i < numThreads; i++) {
// Neuen Thread initialisieren und im Array speichern
threadSpeicher[i] = new LeibnizThread(numThreads, i);
//Thread starten
threadSpeicher[i].start();
}
//Warten bis alle Threads fertig sind und ihr ergebnis berechnet haben
for(LeibnizThread w : threadSpeicher)
try {
w.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BigDecimal sum = new BigDecimal(0.0);
//Summe aller Threads zusammenrechnen
for(LeibnizThread w : threadSpeicher) {
System.out.println(w.getResult() + " Zwischenergebnis");
sum = sum.add(w.getResult());
}
//Summe wird mit 4 multipliziert, um finales Ergebnis zu erhalten
this.value = sum.multiply(new BigDecimal(4));
System.out.println("Ergebnis: " + this.value);
return true;
}
//Methode soll Threads aus Methode startCalculation(numThreads) stoppen, aber wie ?
#Override
public void stopCalculation() {
flag = true;
}
And my Thread class looks like that:
public class LeibnizThread extends Thread {
private int threadRemainder;
private int numThreads;
private BigDecimal result = new BigDecimal(0.0);
private volatile boolean flag = false;
public LeibnizThread(int threadCount, int threadRemainder) {
this.numThreads = threadCount;
this.threadRemainder = threadRemainder;
}
public void run() {
BigDecimal counter = new BigDecimal("1");
while( !flag ) {
if(counter.intValue() % numThreads == threadRemainder)
if(counter.remainder(new BigDecimal("2")).equals(BigDecimal.ONE)) {
result = result.add(BigDecimal.ONE.divide(((new BigDecimal("2").multiply(counter).subtract(BigDecimal.ONE))), 100, RoundingMode.HALF_UP));
}else {
result = result.subtract(BigDecimal.ONE.divide(((new BigDecimal("2").multiply(counter).subtract(BigDecimal.ONE))), 100, RoundingMode.HALF_UP));
}
counter = counter.add(new BigDecimal("1"));
}
}
public BigDecimal getResult() {
return this.result;
}
public void setFlagTrue() {
flag = true;
}
}
I tried to implement a "flag" to make it stop but i dont know how to get impact on the threads which are initialized in the method "startCalculation(numThreads)" from the method "stopCalculation()" .
If anyone has an idea please let me know. Have a nice day and stay healthy :)
To preface; I haven't built and run your code and I haven't really looked up the Leibniz formula, so I'll just keep this answer to your threading question.
It looks like you are facing two problems here:
Calling w.join() will cause your execution to wait until the thread finishes. Unfortunately, the thread will never finish because you will never exit startCalculation(). This is called a deadlock and it's caused when one thread is forever waiting for another to finish.
Even if your execution got to that point, you don't know how to tell the threads to stop.
For the first issue, my advice would be to use one of Java's other helpful thread classes. In this case, you should change LeibnizThread to implement Runnable instead of extending Thread. This will still cause a new thread to be created, but you mostly don't need to worry about the specifics.
For the second issue, you can just move the array of threads out of the method so it gets scoped at the class level. Then, in stopCalculation() you can loop through the threads and tell them to stop.
I wrote up a basic framework for how you can use Runnables in cases like this. Note that this is only one way to do it and there are tons of helpful classes in Java's concurrency library. So look around and see all the tools that are available!
package com.sandbox;
import java.math.BigDecimal;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Leibniz implements CalculatePi {
private Worker[] workers;
#Override
public boolean startCalculation(int numThreads) {
// The executor service handles your thread execution for you
ExecutorService executorService = Executors.newFixedThreadPool(numThreads);
// Start you threads and save a reference to them so you can call them later
workers = new Worker[numThreads];
for (int i = 0; i < numThreads; i++) {
Worker worker = new Worker();
workers[i] = worker;
executorService.submit(worker); // This starts the thread. It calls worker.run().
}
return true;
}
#Override
public void stopCalculation() {
for (Worker worker : workers) {
worker.stopExecution();
}
}
#Override
public BigDecimal getValue() {
BigDecimal result = BigDecimal.ZERO;
for (Worker worker : workers) {
// Do whatever thread consolidation work you need to do here to get a single result
result = result.max(worker.getCurrentResult());
}
return result;
}
private class Worker implements Runnable {
private volatile boolean stopExecution = false; // "volatile" helps make sure the thread actually stops when you want it to by avoiding CPU caches
private BigDecimal currentResult;
Worker() {
// Pass in whatever you need to do the work
}
#Override
public void run() {
while (!stopExecution) {
// Do all of your multi-threaded computation here, setting the currentResult as you go
currentResult = new BigDecimal(System.currentTimeMillis()); // Example.
}
}
void stopExecution() {
this.stopExecution = true;
}
BigDecimal getCurrentResult() {
return currentResult;
}
}
}
And here's a little code that exercises it. It looks a bit like your professor's code.
public static void main(String[] args) throws InterruptedException {
CalculatePi pi = new Leibniz();
pi.startCalculation(4);
for (int i = 0; i < 5; i++) {
sleep(1000);
System.out.println("Current Result: " + pi.getValue());
}
pi.stopCalculation();
BigDecimal finalResult = pi.getValue();
sleep(1000);
BigDecimal verifyFinalResult = pi.getValue();
System.out.println("Workers actually stopped: " + finalResult.equals(verifyFinalResult));
}
Results:
Current Result: 1586477696333
Current Result: 1586477697785
Current Result: 1586477698815
Current Result: 1586477699783
Current Result: 1586477700859
Workers actually stopped: true
I left a lot out because I don't want to do your homework for you, but this should help you get started. Enjoy! :)

Java Concurrency and Multithreading

This is kind of a big question.
I am attempting to create an ordered multiple producer and single consumer scenario in Java. It is ordered in the sense that after producer1, only producer2 gets control of the queue, after which producer3, after which producer1 again and so on and so forth. Just to check if that will work under every scenario, I provided the three producers with three different priorities
producer1 - Thread.NORM_PRIORITY - 4
producer2 - Thread.NORM_PRIORITY + 5
producer3 - Thread.NORM_PRIORITY
Now instead of printing what is being put in the queue and what is being consumed, I'm keeping a counter to count how many times each of the producer threads are being handed control of the queue and in what order, and printing those counts in the consumer thread.
Code is provided after the outputs.
I am confused by one particular behaviour of the threads, the code posted below works as I wanted it to, but if I replace this
while(flag==false)
wait();
if(getIndex()!=next)
return;
in the put() function of q.java, with this
while(flag==false && getIndex()!=next)
wait();
The producer threads are being handed control of the queue erratically. Like with the first code snippet, I am getting the following output, for producers 1,2 and 3 respectively
125 125 125
126 125 125
126 126 125
126 126 126
Producer1 is getting control of the queue first, then 2 then 3, and then 1 again.
But with the alternate option I am getting this output
2 6 8
2 6 8
2 6 8
The same producer keeps getting control of the queue.
Shouldn't the waiting thread NOT gain control of the queue unless it's index matches with the index of the thread which is supposed to get control of the q, like if next is 2, and producer3 is handled control of the queue, shouldn't it go into wait because of the while condition, and the queue be free to be approached by some other thread again, the process repeating until producer2 gets it?
QUEUE
import java.util.*;
class q
{
private volatile int size;
private volatile int clicks[];
private volatile boolean flag;
private volatile int next;
public q(int size)
{
this.size = size;
clicks = new int[size+1];
flag = true;
next = 1;
}
private synchronized int getIndex()
{
String name = Thread.currentThread().getName();
return (int)(name.charAt(name.length()-1))-48;
}
private synchronized void show()
{
//System.out.println("Got control -> "+name+" for index "+index);
if(flag==true)
{
int index = getIndex();
/*
System.out.println("Control provided to "+index);
Scanner s = new Scanner(System.in);
System.out.println("Press enter to continue");
String c = s.next();
*/
clicks[index]+=1;
next = (index%size)+1;
//System.out.println("Provide control to "+next);
}
else
{
int i;
for(i = 1;i<=size;i++)
System.out.print(clicks[i]+" ");
System.out.println();
}
}
public synchronized void put()
{
try
{
while(flag==false)
wait();
if(getIndex()!=next)
return;
show();
flag = false;
notify();
}
catch(Exception e)
{
System.out.println("Exception caught - "+e);
}
}
public synchronized void get()
{
try
{
while(flag==true)
wait();
show();
flag = true;
notifyAll();
}
catch(Exception e)
{
System.out.println("Exception caught - "+e);
}
}
}
PRODUCER
class producer implements Runnable
{
private q queue;
public producer(q queue)
{
this.queue = queue;
}
public void run()
{
try
{
//int i;
while(true)
queue.put();
}
catch(Exception e)
{
System.out.println("Exception caught - "+e);
}
}
}
CONSUMER
class consumer implements Runnable
{
private q queue;
public consumer(q queue)
{
this.queue = queue;
}
public void run()
{
try
{
while(true)
queue.get();
}
catch(Exception e)
{
System.out.println("Exception caught - "+e);
}
}
}
TESTCLASS
class testclass
{
private q queue;
private producer p1; //lowest priority
private producer p2; //highest priority
private producer p3; //normal priority
private consumer c;
private Thread pt1;
private Thread pt2;
private Thread pt3;
private Thread ct;
public testclass()
{
queue = new q(3);
p1 = new producer(queue);
p2 = new producer(queue);
p3 = new producer(queue);
c = new consumer(queue);
pt1 = new Thread(p1,"producer1");
pt2 = new Thread(p2,"producer2");
pt3 = new Thread(p3,"producer3");
ct = new Thread(c,"consumer");
}
public void begin()
{
pt2.setPriority(Thread.NORM_PRIORITY + 5);
pt1.setPriority(Thread.NORM_PRIORITY - 4);
//pt3.setPriority(Thread.NORM_PRIORITY - 3);
pt1.start();
pt2.start();
pt3.start();
ct.start();
}
public static void main(String args[])
{
try
{
testclass t = new testclass();
t.begin();
}
catch(Exception e)
{
System.out.println("Exception caught - "+e);
}
}
}
It looks like you are dealing with threads and concurrency but not.
You are dealing with logical operators:
Your code
while(flag==false && getIndex()!=next)
wait();
If flag is true then your logical expression will be false and the execution will go on. What you really need is:
while(flag==false || getIndex()!=next)
wait();
There are so many things wrong with this code, it is hard to tell where the actual problem is. I strongly suggest that you upgrade your knowledge on threading first by reading a good book on the topic.
The major problem here is that you confuse thread priority with order of execution. In general the order of execution with threads is undefined, and unless you enforce the order, there is no order. The only thing that thread priority does is to specify which thread is put on hold if there are more running threads than CPUs that can execute them. It will not enforce any order of execution otherwise.
I.E. when several threads try to enter a synchronized function, then one of them is granted access, but which one that will be is not specified. It could be the high priority thread, but it could also be any other as well. Since all your functions are synchronized all threads are constantly put on hold, therefore even thread priority won't do a thing, because most of the time threads are waiting on their lock anyways.

The issue for multi-thread in java [duplicate]

What is a way to simply wait for all threaded process to finish? For example, let's say I have:
public class DoSomethingInAThread implements Runnable{
public static void main(String[] args) {
for (int n=0; n<1000; n++) {
Thread t = new Thread(new DoSomethingInAThread());
t.start();
}
// wait for all threads' run() methods to complete before continuing
}
public void run() {
// do something here
}
}
How do I alter this so the main() method pauses at the comment until all threads' run() methods exit? Thanks!
You put all threads in an array, start them all, and then have a loop
for(i = 0; i < threads.length; i++)
threads[i].join();
Each join will block until the respective thread has completed. Threads may complete in a different order than you joining them, but that's not a problem: when the loop exits, all threads are completed.
One way would be to make a List of Threads, create and launch each thread, while adding it to the list. Once everything is launched, loop back through the list and call join() on each one. It doesn't matter what order the threads finish executing in, all you need to know is that by the time that second loop finishes executing, every thread will have completed.
A better approach is to use an ExecutorService and its associated methods:
List<Callable> callables = ... // assemble list of Callables here
// Like Runnable but can return a value
ExecutorService execSvc = Executors.newCachedThreadPool();
List<Future<?>> results = execSvc.invokeAll(callables);
// Note: You may not care about the return values, in which case don't
// bother saving them
Using an ExecutorService (and all of the new stuff from Java 5's concurrency utilities) is incredibly flexible, and the above example barely even scratches the surface.
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class DoSomethingInAThread implements Runnable
{
public static void main(String[] args) throws ExecutionException, InterruptedException
{
//limit the number of actual threads
int poolSize = 10;
ExecutorService service = Executors.newFixedThreadPool(poolSize);
List<Future<Runnable>> futures = new ArrayList<Future<Runnable>>();
for (int n = 0; n < 1000; n++)
{
Future f = service.submit(new DoSomethingInAThread());
futures.add(f);
}
// wait for all tasks to complete before continuing
for (Future<Runnable> f : futures)
{
f.get();
}
//shut down the executor service so that this thread can exit
service.shutdownNow();
}
public void run()
{
// do something here
}
}
instead of join(), which is an old API, you can use CountDownLatch. I have modified your code as below to fulfil your requirement.
import java.util.concurrent.*;
class DoSomethingInAThread implements Runnable{
CountDownLatch latch;
public DoSomethingInAThread(CountDownLatch latch){
this.latch = latch;
}
public void run() {
try{
System.out.println("Do some thing");
latch.countDown();
}catch(Exception err){
err.printStackTrace();
}
}
}
public class CountDownLatchDemo {
public static void main(String[] args) {
try{
CountDownLatch latch = new CountDownLatch(1000);
for (int n=0; n<1000; n++) {
Thread t = new Thread(new DoSomethingInAThread(latch));
t.start();
}
latch.await();
System.out.println("In Main thread after completion of 1000 threads");
}catch(Exception err){
err.printStackTrace();
}
}
}
Explanation:
CountDownLatch has been initialized with given count 1000 as per your requirement.
Each worker thread DoSomethingInAThread will decrement the CountDownLatch, which has been passed in constructor.
Main thread CountDownLatchDemo await() till the count has become zero. Once the count has become zero, you will get below line in output.
In Main thread after completion of 1000 threads
More info from oracle documentation page
public void await()
throws InterruptedException
Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted.
Refer to related SE question for other options:
wait until all threads finish their work in java
Avoid the Thread class altogether and instead use the higher abstractions provided in java.util.concurrent
The ExecutorService class provides the method invokeAll that seems to do just what you want.
Consider using java.util.concurrent.CountDownLatch. Examples in javadocs
Depending on your needs, you may also want to check out the classes CountDownLatch and CyclicBarrier in the java.util.concurrent package. They can be useful if you want your threads to wait for each other, or if you want more fine-grained control over the way your threads execute (e.g., waiting in their internal execution for another thread to set some state). You could also use a CountDownLatch to signal all of your threads to start at the same time, instead of starting them one by one as you iterate through your loop. The standard API docs have an example of this, plus using another CountDownLatch to wait for all threads to complete their execution.
As Martin K suggested java.util.concurrent.CountDownLatch seems to be a better solution for this. Just adding an example for the same
public class CountDownLatchDemo
{
public static void main (String[] args)
{
int noOfThreads = 5;
// Declare the count down latch based on the number of threads you need
// to wait on
final CountDownLatch executionCompleted = new CountDownLatch(noOfThreads);
for (int i = 0; i < noOfThreads; i++)
{
new Thread()
{
#Override
public void run ()
{
System.out.println("I am executed by :" + Thread.currentThread().getName());
try
{
// Dummy sleep
Thread.sleep(3000);
// One thread has completed its job
executionCompleted.countDown();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
try
{
// Wait till the count down latch opens.In the given case till five
// times countDown method is invoked
executionCompleted.await();
System.out.println("All over");
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
If you make a list of the threads, you can loop through them and .join() against each, and your loop will finish when all the threads have. I haven't tried it though.
http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#join()
Create the thread object inside the first for loop.
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new Runnable() {
public void run() {
// some code to run in parallel
}
});
threads[i].start();
}
And then so what everyone here is saying.
for(i = 0; i < threads.length; i++)
threads[i].join();
You can do it with the Object "ThreadGroup" and its parameter activeCount:
As an alternative to CountDownLatch you can also use CyclicBarrier e.g.
public class ThreadWaitEx {
static CyclicBarrier barrier = new CyclicBarrier(100, new Runnable(){
public void run(){
System.out.println("clean up job after all tasks are done.");
}
});
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
Thread t = new Thread(new MyCallable(barrier));
t.start();
}
}
}
class MyCallable implements Runnable{
private CyclicBarrier b = null;
public MyCallable(CyclicBarrier b){
this.b = b;
}
#Override
public void run(){
try {
//do something
System.out.println(Thread.currentThread().getName()+" is waiting for barrier after completing his job.");
b.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
To use CyclicBarrier in this case barrier.await() should be the last statement i.e. when your thread is done with its job. CyclicBarrier can be used again with its reset() method. To quote javadocs:
A CyclicBarrier supports an optional Runnable command that is run once per barrier point, after the last thread in the party arrives, but before any threads are released. This barrier action is useful for updating shared-state before any of the parties continue.
The join() was not helpful to me. see this sample in Kotlin:
val timeInMillis = System.currentTimeMillis()
ThreadUtils.startNewThread(Runnable {
for (i in 1..5) {
val t = Thread(Runnable {
Thread.sleep(50)
var a = i
kotlin.io.println(Thread.currentThread().name + "|" + "a=$a")
Thread.sleep(200)
for (j in 1..5) {
a *= j
Thread.sleep(100)
kotlin.io.println(Thread.currentThread().name + "|" + "$a*$j=$a")
}
kotlin.io.println(Thread.currentThread().name + "|TaskDurationInMillis = " + (System.currentTimeMillis() - timeInMillis))
})
t.start()
}
})
The result:
Thread-5|a=5
Thread-1|a=1
Thread-3|a=3
Thread-2|a=2
Thread-4|a=4
Thread-2|2*1=2
Thread-3|3*1=3
Thread-1|1*1=1
Thread-5|5*1=5
Thread-4|4*1=4
Thread-1|2*2=2
Thread-5|10*2=10
Thread-3|6*2=6
Thread-4|8*2=8
Thread-2|4*2=4
Thread-3|18*3=18
Thread-1|6*3=6
Thread-5|30*3=30
Thread-2|12*3=12
Thread-4|24*3=24
Thread-4|96*4=96
Thread-2|48*4=48
Thread-5|120*4=120
Thread-1|24*4=24
Thread-3|72*4=72
Thread-5|600*5=600
Thread-4|480*5=480
Thread-3|360*5=360
Thread-1|120*5=120
Thread-2|240*5=240
Thread-1|TaskDurationInMillis = 765
Thread-3|TaskDurationInMillis = 765
Thread-4|TaskDurationInMillis = 765
Thread-5|TaskDurationInMillis = 765
Thread-2|TaskDurationInMillis = 765
Now let me use the join() for threads:
val timeInMillis = System.currentTimeMillis()
ThreadUtils.startNewThread(Runnable {
for (i in 1..5) {
val t = Thread(Runnable {
Thread.sleep(50)
var a = i
kotlin.io.println(Thread.currentThread().name + "|" + "a=$a")
Thread.sleep(200)
for (j in 1..5) {
a *= j
Thread.sleep(100)
kotlin.io.println(Thread.currentThread().name + "|" + "$a*$j=$a")
}
kotlin.io.println(Thread.currentThread().name + "|TaskDurationInMillis = " + (System.currentTimeMillis() - timeInMillis))
})
t.start()
t.join()
}
})
And the result:
Thread-1|a=1
Thread-1|1*1=1
Thread-1|2*2=2
Thread-1|6*3=6
Thread-1|24*4=24
Thread-1|120*5=120
Thread-1|TaskDurationInMillis = 815
Thread-2|a=2
Thread-2|2*1=2
Thread-2|4*2=4
Thread-2|12*3=12
Thread-2|48*4=48
Thread-2|240*5=240
Thread-2|TaskDurationInMillis = 1568
Thread-3|a=3
Thread-3|3*1=3
Thread-3|6*2=6
Thread-3|18*3=18
Thread-3|72*4=72
Thread-3|360*5=360
Thread-3|TaskDurationInMillis = 2323
Thread-4|a=4
Thread-4|4*1=4
Thread-4|8*2=8
Thread-4|24*3=24
Thread-4|96*4=96
Thread-4|480*5=480
Thread-4|TaskDurationInMillis = 3078
Thread-5|a=5
Thread-5|5*1=5
Thread-5|10*2=10
Thread-5|30*3=30
Thread-5|120*4=120
Thread-5|600*5=600
Thread-5|TaskDurationInMillis = 3833
As it's clear when we use the join:
The threads are running sequentially.
The first sample takes 765 Milliseconds while the second sample takes 3833 Milliseconds.
Our solution to prevent blocking other threads was creating an ArrayList:
val threads = ArrayList<Thread>()
Now when we want to start a new thread we most add it to the ArrayList:
addThreadToArray(
ThreadUtils.startNewThread(Runnable {
...
})
)
The addThreadToArray function:
#Synchronized
fun addThreadToArray(th: Thread) {
threads.add(th)
}
The startNewThread funstion:
fun startNewThread(runnable: Runnable) : Thread {
val th = Thread(runnable)
th.isDaemon = false
th.priority = Thread.MAX_PRIORITY
th.start()
return th
}
Check the completion of the threads as below everywhere it's needed:
val notAliveThreads = ArrayList<Thread>()
for (t in threads)
if (!t.isAlive)
notAliveThreads.add(t)
threads.removeAll(notAliveThreads)
if (threads.size == 0){
// The size is 0 -> there is no alive threads.
}
The problem with:
for(i = 0; i < threads.length; i++)
threads[i].join();
...is, that threads[i + 1] never can join before threads[i].
Except the "latch"ed ones, all solutions have this lack.
No one here (yet) mentioned ExecutorCompletionService, it allows to join threads/tasks according to their completion order:
public class ExecutorCompletionService<V>
extends Object
implements CompletionService<V>
A CompletionService that uses a supplied Executor to execute tasks. This class arranges that submitted tasks are, upon completion, placed on a queue accessible using take. The class is lightweight enough to be suitable for transient use when processing groups of tasks.
Usage Examples.
Suppose you have a set of solvers for a certain problem, each returning a value of some type Result, and would like to run them concurrently, processing the results of each of them that return a non-null value, in some method use(Result r). You could write this as:
void solve(Executor e, Collection<Callable<Result>> solvers) throws InterruptedException, ExecutionException {
CompletionService<Result> cs = new ExecutorCompletionService<>(e);
solvers.forEach(cs::submit);
for (int i = solvers.size(); i > 0; i--) {
Result r = cs.take().get();
if (r != null)
use(r);
}
}
Suppose instead that you would like to use the first non-null result of the set of tasks, ignoring any that encounter exceptions, and cancelling all other tasks when the first one is ready:
void solve(Executor e, Collection<Callable<Result>> solvers) throws InterruptedException {
CompletionService<Result> cs = new ExecutorCompletionService<>(e);
int n = solvers.size();
List<Future<Result>> futures = new ArrayList<>(n);
Result result = null;
try {
solvers.forEach(solver -> futures.add(cs.submit(solver)));
for (int i = n; i > 0; i--) {
try {
Result r = cs.take().get();
if (r != null) {
result = r;
break;
}
} catch (ExecutionException ignore) {}
}
} finally {
futures.forEach(future -> future.cancel(true));
}
if (result != null)
use(result);
}
Since: 1.5 (!)
Assuming use(r) (of Example 1) also asynchronous, we had a big advantage. #

Create a simple queue with Java threads

I'm trying to create a simple queue with Java Thread that would allow a loop, say a for loop with 10 iterations, to iterate n (< 10) threads at a time and wait until those threads are finished before continuing to iterate.
Here's a better way to illustrate my problem:
for (int i = 1; i <= 10; i++) {
new Thread ( do_some_work() );
if ( no_available_threads ) {
wait_until_available_threads();
}
}
do_some_work() {
// do something that takes a long time
}
Basically what I want to do is a copy of this: Thread and Queue
How can I achieve this the most painless way?
I would use the Java 5 Executors instead of rolling your own. Something like the following:
ExecutorService service = Executors.newFixedThreadPool(10);
// now submit our jobs
service.submit(new Runnable() {
public void run() {
do_some_work();
}
});
// you can submit any number of jobs and the 10 threads will work on them
// in order
...
// when no more to submit, call shutdown, submitted jobs will continue to run
service.shutdown();
// now wait for the jobs to finish
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
Use the Executors, as recommended by the others. However, if you want the fun of doing it yourself, try something like this. (Take care. I wrote it in Notepad and there's some Exceptions you'll need to catch even if I got everything else right. Notepad's poor at catching coding errors.) This is more a concept than an actual solution to anything, but the idea could be generally useful.
private ConcurrentLinkedQueue<MyThread> tQueue =
new ConcurrentLinkedQueue<MyThread>();
class MyThread extends Thread {
public Runnable doSomething;
public void run() {
// Do the real work.
doSomething();
// Clean up and make MyThread available again.
tQueue.add( mythread );
// Might be able to avoid this synch with clever code.
// (Don't synch if you know no one's waiting.)
// (But do that later. Much later.)
synchronized (tQueue) {
// Tell them the queue is no longer empty.
tQueue.notifyAll();
}
}
}
Elsewhere:
// Put ten MyThreads in tQueue.
for (int i = 0; i < 10; i++) tQueue.add( new MyThread() );
// Main Loop. Runs ten threads endlessly.
for (;;) {
MyThread t = tQueue.poll();
if (t == null) {
// Queue empty. Sleep till someone tells us it's not.
do {
// There's a try-catch combo missing here.
synchonized( tQueue ) { tQueue.wait() };
t = tQueue.poll();
} while (t == null) break; // Watch for fake alert!
}
t.doSomething = do_some_work;
t.start();
}
Also, note the clever use of ConcurrentLinkedQueue. You could use something else like ArrayList or LinkedList, but you'd need to synchronize them.
see java.util.concurrent and especially Executors and ExecutorService
Crate Logger.class :
public class Logger extends Thread {
List<String> queue = new ArrayList<String>();
private final int MAX_QUEUE_SIZE = 20;
private final int MAX_THREAD_COUNT = 10;
#Override
public void start() {
super.start();
Runnable task = new Runnable() {
#Override
public void run() {
while (true) {
String message = pullMessage();
Log.d(Thread.currentThread().getName(), message);
// Do another processing
}
}
};
// Create a Group of Threads for processing
for (int i = 0; i < MAX_THREAD_COUNT; i++) {
new Thread(task).start();
}
}
// Pulls a message from the queue
// Only returns when a new message is retrieves
// from the queue.
private synchronized String pullMessage() {
while (queue.isEmpty()) {
try {
wait();
} catch (InterruptedException e) {
}
}
return queue.remove(0);
}
// Push a new message to the tail of the queue if
// the queue has available positions
public synchronized void pushMessage(String logMsg) {
if (queue.size() < MAX_QUEUE_SIZE) {
queue.add(logMsg);
notifyAll();
}
}
}
Then insert bellow code in your main class :
Logger logger =new Logger();
logger.start();
for ( int i=0; i< 10 ; i++) {
logger.pushMessage(" DATE : "+"Log Message #"+i);
}

Categories