CountDownLatch - understanding await and countDown - java

According to Javadoc:
A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero.
That means in the below code, since I initialized the CountDownLatch to 1. All threads should get unblocked from its await method as soon as the latch calls countdown.
But, the main thread is waiting for all the threads to complete. And also, I didn't join the main thread to end of the other threads. Why is the main thread waiting?
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
public class Sample implements Runnable {
private CountDownLatch latch;
public Sample(CountDownLatch latch)
{
this.latch = latch;
}
private static AtomicLong number = new AtomicLong(0);
public long next() {
return number.getAndIncrement();
}
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(1);
for (int threadNo = 0; threadNo < 4000; threadNo++) {
Runnable t = new Sample(latch);
new Thread(t).start();
}
try {
latch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void run() {
try {
latch.await();
Thread.sleep(100);
System.out.println("Count:"+next());
} catch (Exception e) {
e.printStackTrace();
}
}
}

Try running the following modified version of your code:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
public class Test implements Runnable {
private CountDownLatch latch;
public Test(CountDownLatch latch)
{
this.latch = latch;
}
private static AtomicLong number = new AtomicLong(0);
public long next() {
return number.getAndIncrement();
}
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(1);
for (int threadNo = 0; threadNo < 1000; threadNo++) {
Runnable t = new Test(latch);
new Thread(t).start();
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( "done" );
}
#Override
public void run() {
try {
Thread.sleep(1000 + (int) ( Math.random() * 3000 ));
System.out.println(next());
} catch (Exception e) {
e.printStackTrace();
} finally {
latch.countDown();
}
}
}
You should see something like:
0 done 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
This indicates that the main thread did, in fact, unblock from the latch.await() call after the first thread called latch.countDown()

you are starting 4000 threads and they are only waiting 100 milliseconds. you are most likely overwhelming the box (and all threads will be ending at roughly the same time). add a sleep in your thread start look and try increasing the timeout to see it work as your expect.

Related

how to create loops with threads (creates several new threads in a loop)?

how can I create a loop (or something else if that is a better way) where I can create some new threads.
So far I have 2 producer and consumer threads. But I would like to create, for example, 5 producers and 5 consumers, and each thread produced / consumed a different "product", two threads cannot do the same.
I'd like it to be something like this:
Produced thread0 produce 0
Consume thread0 consume 0
....
Produced thread4 produce 4
Consume thread4 consume 4
Thank you for every hint.
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ProducerConsumer {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(2);
Thread producerThread = new Thread(new Runnable() {
#Override
public void run() {
try {
int value = 0;
while (true) {
blockingQueue.put(value);
System.out.println("Produced " + value);
value++;
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread consumerThread = new Thread(new Runnable() {
#Override
public void run() {
try {
while (true) {
int value = blockingQueue.take();
System.out.println("Consume " + value);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
producerThread.start();
consumerThread.start();
producerThread.join();
consumerThread.join();
}
}
Use a thread pool (Executors.newFixedThreadpool or Executors.newCachedThreadPool)
Don't forget to manage thread synchronization for resources using synchronized blocks.
Use volatile keyword for values that will be written/read simutaneously by several threads (see What is the volatile keyword useful for?)
I've used lambda syntax to redefine your runnables for clarity.
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ProducerConsumer {
private static volatile int prodValue = 0;
private static final Object valueSync = new Object();
public static void main(String[] args) throws InterruptedException {
final BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(2);
final ExecutorService threadPool = Executors.newCachedThreadPool();
final Runnable producer = () -> {
try {
while (true) {
synchronized(valueSync) {
blockingQueue.put(prodValue);
System.out.println(Thread.currentThread().getId() + " Produced " + prodValue);
prodValue++;
}
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
final Runnable consumer = () -> {
try {
while (true) {
int value = blockingQueue.take();
System.out.println(Thread.currentThread().getId() + " Consumed " + value);
Thread.sleep(1200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
for (int i = 0; i < 5; i++) { //Create 5 threads of each
System.out.println("Loop " + i);
threadPool.execute(producer);
threadPool.execute(consumer);
Thread.sleep(500); //Wait a little
}
System.out.println("Loop done");
//Wait for all threads to complete with timeout
threadPool.awaitTermination(15, TimeUnit.SECONDS);
System.out.println("STOP !");
//Forceful shutdown of all threads (will happen as all threads are in a while(true) loop
threadPool.shutdownNow();
}
}
About synchronization: here you want your value to be added to the queue and incremented seemingly at once (atomically). synchronized around the operations prevents threads from simultaneously running this piece of code, which would result in the same value added multiple times into the queue, and then incremented multiple times (it happens if you decrease the Thread.sleep values to something close to 0 and remove the synchronized block).
I could have used blockingQueue as argument for synchronized but chose to use a dedicated object to make it more obvious.

What concurrently bug is in this program?

I have one program with strange concurrently bug.
What this program does:
Execute event loop each EVENT_LOOP_PAUSE_DURATION_IN_MS.
For each given task execute processor TaskProcessor
Each 500 ms prints queue size of my executor.
I want to have at most one task in queue per taskId. So, when I add task in queue, I check whether tasks has already existed or not. If there is no task, I add it. In the end of task processing, I remove task from activeTasks map.
If you run the program, then you see the following output:
ERROR: 50
ERROR: 70
ERROR: 80
ERROR: 90
ERROR: 110
ERROR: 120
ERROR: 120
ERROR: 140
So, there is a bug. I don't know why, but size of thread pool queue is infinitely increasing.
You can see, that I remove active tasks in 2 point of program:
In finally block of TaskProcessor, when task has processed.
I remove stale tasks in event loop.
So, if I remove code, which removes tasks at point (2), then the bug disappears. I don't understand this behavior.
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Program {
private static final int NUMBER_OF_TASKS = 40;
private static final int NUMBER_OF_THREADS = 10;
private static final long EVENT_LOOP_PAUSE_DURATION_IN_MS = 40L;
class QueueSizePrinter extends Thread {
private final LinkedBlockingQueue<Runnable> workQueue;
public QueueSizePrinter(LinkedBlockingQueue<Runnable> workQueue) {
this.workQueue = workQueue;
}
#Override
public void run() {
while (true) {
int qSize = workQueue.size();
if (qSize > NUMBER_OF_TASKS) {
System.out.println("ERROR: " + qSize);
}
try {
Thread.sleep(500L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class TaskProcessor implements Runnable {
private final String currentTaskId;
private final ConcurrentHashMap<String, Long> activeTasks;
public TaskProcessor(String currentTaskId, ConcurrentHashMap<String, Long> activeTasks) {
this.currentTaskId = currentTaskId;
this.activeTasks = activeTasks;
}
#Override
public void run() {
try {
// emulate of useful work
Thread.sleep(300L);
} catch (Exception e) {
System.out.println("error: " + e.toString());
} finally {
activeTasks.remove(currentTaskId); // (1)
}
}
}
public void program() {
LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
ExecutorService executor = new ThreadPoolExecutor(NUMBER_OF_THREADS, NUMBER_OF_THREADS, 0L, TimeUnit.MILLISECONDS, workQueue);
Set<String> initialTasks = ConcurrentHashMap.newKeySet();
for (int currentTaskIndex = 0; currentTaskIndex < NUMBER_OF_TASKS; currentTaskIndex++) {
initialTasks.add(String.valueOf(currentTaskIndex));
}
new QueueSizePrinter(workQueue).start();
ConcurrentHashMap<String, Long> activeTasks = new ConcurrentHashMap<>();
while (true) {
initialTasks.forEach((currentTaskId) -> {
if (!activeTasks.containsKey(currentTaskId)) {
activeTasks.put(currentTaskId, System.currentTimeMillis());
executor.submit(new TaskProcessor(currentTaskId, activeTasks));
}
});
// (2)
activeTasks.entrySet().removeIf(entry -> {
boolean hasDelete = System.currentTimeMillis() - entry.getValue() > 1000;
if (hasDelete) {
//System.out.println("DELETE id=" + entry.getKey());
}
return hasDelete;
});
try {
Thread.sleep(EVENT_LOOP_PAUSE_DURATION_IN_MS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Program main = new Program();
main.program();
}
}
Problem is at point (2), You are removing stale tasks from activeTasks map. But they are still submitted to ExecutorService. Since You removed it from the map, when while loop execute another cycle, the same task will be resubmitted to ExecutorService. This causes task numbers to increase.

Threading in Sequence

I am trying to learn how to write a program which performs a given set of tasks in sequence with the help of threads. For example, Writing a program which have 3 different threads print 1111…, 22222…., 333333……, so that the output will be 1,2,3,1,2,3,1,2,3…..? OR for e.g. 2 threads one is printing odd numbers and other even numbers, but the output should be printed in sequence - i.e. one even and then odd.
I would like to learn how to write similar kind of programs in which different threads print different stuff concurrently and the output should be printed in sequence.
What is the basic concept in writing these programs. Can we use ThreadPools/Executors for the purpose ? For e.g. can we use
ExecutorService exectorService = Executors.newFixedThreadPool(3);
Can we use Future, FurtureTask, Callable, execute, submit ...? I know these concepts but I am not able to connect the dots for solving the above scenarios.
Please guide me how to go about writing these kind of programs using multithreading / concurrency.
I have written a program using wait()/notifyAll(). Following is the program. I am not executing the consumer as I am printing the whole sequence at the end. Also I am limiting the capacity of the queue to be 15. So I am basically printing the odd / even range till 15.
public class ProduceEven implements Runnable {
private final List<Integer> taskQueue;
private final int MAX_CAPACITY;
public ProduceEven (List<Integer> sharedQueue, int size) {
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
}
#Override
public void run() {
// TODO Auto-generated method stub
int counter = 0;
while (counter < 15) {
try {
produce(counter++);
} catch (InterruptedException e) {
e.getMessage();
}
}
}
private void produce (int i) throws InterruptedException {
synchronized (taskQueue) {
while (taskQueue.size() == MAX_CAPACITY) {
System.out.println("Queue is full : "+Thread.currentThread().getName()+" is waiting , size: "+ taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
if(i%2==0) {
taskQueue.add(i);
}
taskQueue.notifyAll();
}
}
}
public class ProduceOdd implements Runnable {
private final List<Integer> taskQueue;
private final int MAX_CAPACITY;
public ProduceOdd (List<Integer> sharedQueue, int size) {
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
}
#Override
public void run() {
int counter = 0;
while (counter < 15) {
try {
produce(counter++);
} catch (InterruptedException e) {
e.getMessage();
}
}
}
private void produce (int i) throws InterruptedException {
synchronized (taskQueue) {
while (taskQueue.size() == MAX_CAPACITY) {
System.out.println("Queue is full : "+Thread.currentThread().getName()+" is waiting , size: "+ taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
if(i%2==1) {
taskQueue.add(i);
}
taskQueue.notify();
}
}
}
public class OddEvenExampleWithWaitAndNotify {
public static void main(String[] args) {
List<Integer> taskQueue = new ArrayList<Integer>();
int MAX_CAPACITY = 15;
Thread tProducerEven = new Thread(new ProduceEven(taskQueue, MAX_CAPACITY), "Producer Even");
Thread tProducerOdd = new Thread(new ProduceOdd(taskQueue, MAX_CAPACITY), "Producer Odd");
tProducerEven.start();
tProducerOdd.start();
try {
tProducerEven.join();
tProducerOdd.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
ListIterator listIterator = taskQueue.listIterator();
System.out.println("Elements Are:: ");
while(listIterator.hasNext()) {
System.out.print(listIterator.next()+" ");
}
}
}
The output which I get is: Elements Are:: 02134657911810131214
The output is all jumbled up. Why is it not in sequence. 01234567891011121314 What am I missing. I would be now trying to make the program using Semaphores. Also how do we make this program using explicit locks?
Yes, you can use ExecutorService as a starting point to run your threads. You can also create and start your Threads manually, that would make no difference.
The important thing is that your Threads will run in parallel if you do not synchronize them (i.e., they have to wait for one another). To synchronize you can, e.g. use Semaphores or other thread communication mechanisms.
You wrote in the comments you have written a producer/consumer program. It's a bit of the same thing. Each time the 1-Thread produces a 1, the 2-Thread must know that it can now produce a 2. When it is finished, it must let the 3-Thread know that it must produce a 3. The basic concepts are the same. Just the threads have both producer and consumer roles.
Hi this is one sample program to print Odd and Even using two thread and using thread synchronization among them.
Also we have used Executor framework which is not mandatory, you can create thread using new Thread() as well. For quick prototype I have used system.exit() which can be replaced with graceful shutdown of threads like, interruption and all.
package com.ones.twos.threes;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class OnesTwos {
public static void main(String[] args) {
BlockingQueue<Integer> bq1 = new ArrayBlockingQueue<Integer>(100);
BlockingQueue<Integer> bq2 = new ArrayBlockingQueue<Integer>(100);
ExecutorService executorService = Executors.newFixedThreadPool(2);
try {
bq1.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
executorService.submit(new OddEven(bq1, bq2));
executorService.submit(new OddEven(bq2, bq1));
executorService.shutdown();
}
public static class OddEven implements Runnable {
BlockingQueue<Integer> bq1;
BlockingQueue<Integer> bq2;
public OddEven(BlockingQueue<Integer> bq1, BlockingQueue<Integer> bq2) {
this.bq1 = bq1;
this.bq2 = bq2;
}
#Override
public void run() {
while (true) {
try {
int take = bq1.take();
System.out.println(take);
bq2.offer(take + 1);
if (take > 20)
System.exit(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Mycode is also similar to Anirban's, except I am not using executor framework,
public class TestThread {
public static void main(String[] args) {
Boolean bol = new Boolean(true);
(new Thread(new Odd(bol), "odd")).start();
(new Thread(new Even(bol), "even")).start();
}
}
public class Even implements Runnable {
private Boolean flag;
public Even(Boolean b) {
this.flag = b;
}
#Override
public void run() {
for (int i = 2; i < 20; i = i + 2) {
synchronized (flag) {
try {
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(1000);
flag.notify();
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Odd implements Runnable {
private Boolean flag;
public Odd(Boolean b) {
this.flag = b;
}
#Override
public void run() {
for (int i = 1; i < 20; i = i + 2) {
synchronized (flag) {
try {
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(1000);
flag.notify();
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
By establishing the thread pool of 3 (ExecutorService exectorService = Executors.newFixedThreadPool(3); you are essentilly limiting the executor capacity to 3 and other incoming threads will be on hold. If you want to run them in paralel you can just submit them at once. If you want to wait for each other and want to find out the result I suggest you use Callable. Personally I really like Callable because after submiting it you can just call the get method of Future, wait for a returned value from the executed thread and then continue to the next one. From the API you can see this:
/**
* Submits a value-returning task for execution and returns a
* Future representing the pending results of the task. The
* Future's {#code get} method will return the task's result upon
* successful completion.
*
*
* If you would like to immediately block waiting
* for a task, you can use constructions of the form
* {#code result = exec.submit(aCallable).get();}
And a very good example here. If you go for the Callable alternative then you don't need a Thread pool. Just a normal executor is fine. Remember to shut the executor down in the end.
class MyNumber {
int i = 1;
}
class Task implements Runnable {
MyNumber myNumber;
int id;
Task(int id, MyNumber myNumber) {
this.id = id;
this.myNumber = myNumber;
}
#Override
public void run() {
while (true) {
synchronized (myNumber) {
while (myNumber.i != id) {
try {
myNumber.wait(); //Wait until Thread with correct next number
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(id);
if (myNumber.i == 1) {
myNumber.i = 2;
} else if (myNumber.i == 2) {
myNumber.i = 3;
} else {
myNumber.i = 1;
}
myNumber.notifyAll();
}
}
}
}
In main method:
MyNumber myNumber = new MyNumber();
new Thread(new Task(1, myNumber)).start();
new Thread(new Task(2, myNumber)).start();
new Thread(new Task(3, myNumber)).start();
Hi here we have used 2 thread one to print even and another to print odd.
Both are separate and have no relation to each other.
But we have to do a synchronization mechanism between them. Also we need a mechanism to let the ball rolling, i.e. start one thread printing.
Each thread is waiting on condition and after doing it's task it lets other thread work and put ownself in waiting state.
Well happy path works fine, but we need special care when even thread is not in waiting state and the signal() from main fires, in that case even thread will never able to wake up and the program hangs.
So to make sure main thread successfully sends a signal() to even thread and even thread does not miss that we have used Phaser(with party) and checking even thread state in while loop in main.
Code is as below.
package com.ones.twos.threes;
import java.util.concurrent.Phaser;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class OnesTwosTrial2 {
public static void main(String[] args) {
Lock lk = new ReentrantLock();
Phaser ph = new Phaser(3); // to let main start the even thread
Condition even = lk.newCondition();
Condition odd = lk.newCondition();
OnesTwosTrial2 onestwostrial2 = new OnesTwosTrial2();
Thread ev = onestwostrial2.new Evens(lk, even, odd, ph);
Thread od = onestwostrial2.new Odds(lk, even, odd, ph);
ev.start();
od.start();
System.out.println("in main before arrive");
ph.arriveAndAwaitAdvance();
System.out.println("in main after arrive");
// we have to make sure odd and even thread is
// started and waiting on respective condition.
// So we used Phaser with 3, because we are having here
// 3 parties (threads)
// main, odd,even. We will signal only when all the
// threads have started.
// and waiting on conditions.
while (!Thread.State.WAITING.equals(ev.getState())) {
System.out.println("waiting");
}
lk.lock();
even.signal();
lk.unlock();
}
class Evens extends Thread {
Lock lk;
Condition even;
Condition odd;
Phaser ph;
public Evens(Lock lk, Condition even, Condition odd, Phaser ph) {
this.lk = lk;
this.even = even;
this.odd = odd;
this.ph = ph;
}
#Override
public void run() {
System.out.println("even ph");
int cnt = 0;
while (cnt < 20) {
try {
lk.lock();
ph.arrive();
even.await();
System.out.println(cnt);
cnt += 2;
odd.signal();
lk.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Odds extends Thread {
Lock lk;
Condition even;
Condition odd;
Phaser ph;
public Odds(Lock lk, Condition even, Condition odd, Phaser ph) {
this.lk = lk;
this.even = even;
this.odd = odd;
this.ph = ph;
}
#Override
public void run() {
System.out.println("odd ph");
int cnt = 1;
while (cnt < 20) {
try {
lk.lock();
ph.arrive();
odd.await();
System.out.println(cnt);
cnt += 2;
even.signal();
lk.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

starting 10 different thread in java at the sametime

I have 10 different threads which I want to start at the same time. And by same time, I mean not by starting them sequentially (although this will be close).
What is the best way to achieve this in java?
To be accurate: You will not be able to start all 10 threads at the exact same time. There will be some difference in the order ms or ns. You can just try to minimize this difference. And even then: If you have less cores than threads the first couple of threads will have done some work before the others even run their first instruction.
There's a nice example of using a CountDownLatch for that in the Javaspecialists newsletter The Law of the Corrupt Politician.
public class TestCorruption {
private static final int THREADS = 2;
private static final CountDownLatch latch = new CountDownLatch(THREADS);
private static final BankAccount heinz = new BankAccount(1000);
public static void main(String[] args) {
for (int i = 0; i < THREADS; i++) {
addThread();
}
Timer timer = new Timer(true);
timer.schedule(new TimerTask() {
public void run() {
System.out.println(heinz.getBalance());
}
}, 100, 1000);
}
private static void addThread() {
new Thread() {
{
start();
}
public void run() {
latch.countDown();
try {
latch.await();
} catch (InterruptedException e) {
return;
}
while (true) {
heinz.deposit(100);
heinz.withdraw(100);
}
}
};
}
}
It depends on the number of cores your computer have, those will be the number of started threads on the same time, it is my first comment here so i hope this is correct.
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Practica {
private static final int NUMTHREADS = 10;
public static void main(String[] args) {
CountDownLatch cdl = new CountDownLatch(NUMTHREADS);
ExecutorService executor = Executors.newFixedThreadPool(NUMTHREADS);
for (int i = 0; i < NUMTHREADS; i++) {
executor.submit(new Imp(cdl));
cdl.countDown();
System.out.println("one thread sumbmited "+cdl.getCount());
}
System.out.println("All threads submmited");
executor.shutdown();
}
}
class Imp implements Runnable {
CountDownLatch cdl;
public Imp(CountDownLatch arg) {
this.cdl = arg;
}
#Override
public void run() {
try {
cdl.await();
System.out.printf("STARTED %s at %d millis%n",
Thread.currentThread().getName(),
System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Wait until child threads completed : Java

Problem description : -
Step 1: Take input FILE_NAME from user at main thread.
Step 2: Perform 10 operations on that file (i.e count chars, count lines etc.. ), and all those 10 operations must be in septate threads. It means there must be 10 child threads.
Step 3: Main thread waits until all those child threads completed.
Step 4: Print result.
What I did :-
I did a sample code with 3 threads. I don't want file operation code from your side.
public class ThreadTest {
// This is object to synchronize on.
private static final Object waitObject = ThreadTest.class;
// Your boolean.
private static boolean boolValue = false;
public final Result result = new Result();
public static void main(String[] args) {
final ThreadTest mytest = new ThreadTest();
System.out.println("main started");
new Thread(new Runnable() {
public void run() {
System.out.println("Inside thread");
//Int initialiser
new Thread(new Runnable() {
public void run() {
System.out.println("Setting integer value");
mytest.result.setIntValue(346635);
System.out.println("Integer value seted");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
//String initialiser
new Thread(new Runnable() {
public void run() {
System.out.println("Setting string value");
mytest.result.setStringValue("Hello hi");
System.out.println("String value seted");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
//Boolean initialiser
new Thread(new Runnable() {
public void run() {
System.out.println("Setting boolean value");
mytest.result.setBoolValue(true);
System.out.println("Boolean value seted");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
System.out.println("Thread is finished");
//Notify to main thread
synchronized (ThreadTest.waitObject) {
ThreadTest.boolValue = true;
ThreadTest.waitObject.notifyAll();
}
}
}).start();
try {
synchronized (ThreadTest.waitObject) {
while (!ThreadTest.boolValue) {
ThreadTest.waitObject.wait();
}
}
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out.println("main finished");
System.out.println("Result is : " + mytest.result.toString());
}
}
Problem :-
My above code is not giving correct answer. How can I do that?
Alternate solutions:
CountDownLatch class does the same. But I don't want to use that class.
I looked this similar solution and I want to use methods of Thread only.
You can do:
Thread t = new Thread() {
public void run() {
System.out.println("text");
// other complex code
}
};
t.start();
t.join();
This way you will wait until the thread finishes and just then continue. You can join multiple threads:
for (Thread thread : threads) {
thread.join();
}
I would recommend looking at the Executors framework first, and then look into the CompletionService.
Then you can write something like this:
ExecutorService executor = Executors.newFixedThreadPool(maxThreadsToUse);
CompletionService completion = new ExecutorCompletionService(executor);
for (each sub task) {
completion.submit(new SomeTaskYouCreate())
}
// wait for all tasks to complete.
for (int i = 0; i < numberOfSubTasks; ++i) {
completion.take(); // will block until the next sub task has completed.
}
executor.shutdown();
In Java 8 a far better approach is to use parallelStream()
Note: it is far easier to see exactly what these background tasks are doing.
public static void main(String[] args) {
Stream.<Runnable>of(
() -> mytest.result.setIntValue(346635),
() -> mytest.result.setStringValue("Hello hi"),
() -> mytest.result.setBoolValue(true) )
.parallel()
.forEach(Runnable::run);
System.out.println("main finished");
System.out.println("Result is : " + mytest.result.toString());
}
I took out the debug information and the sleep as these don't alter the outcome.
You may want to choose CountDownLatch from java.util.concurrent. From JavaDocs:
A synchronization aid that allows one or more threads to wait until a
set of operations being performed in other threads completes.
Sample code:
import java.util.concurrent.CountDownLatch;
public class Test {
private final ChildThread[] children;
private final CountDownLatch latch;
public Test() {
this.children = new ChildThread[4];
this.latch = new CountDownLatch(children.length);
children[0] = new ChildThread(latch, "Task 1");
children[1] = new ChildThread(latch, "Task 2");
children[2] = new ChildThread(latch, "Task 3");
children[3] = new ChildThread(latch, "Task 4");
}
public void run() {
startChildThreads();
waitForChildThreadsToComplete();
}
private void startChildThreads() {
Thread[] threads = new Thread[children.length];
for (int i = 0; i < threads.length; i++) {
ChildThread child = children[i];
threads[i] = new Thread(child);
threads[i].start();
}
}
private void waitForChildThreadsToComplete() {
try {
latch.await();
System.out.println("All child threads have completed.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class ChildThread implements Runnable {
private final String name;
private final CountDownLatch latch;
protected ChildThread(CountDownLatch latch, String name) {
this.latch = latch;
this.name = name;
}
#Override
public void run() {
try {
// Implementation
System.out.println(name + " has completed.");
} finally {
latch.countDown();
}
}
}
public static void main(String[] args) {
Test test = new Test();
test.run();
}
}
Output:
Task 1 has completed.
Task 4 has completed.
Task 3 has completed.
Task 2 has completed.
All child threads have completed.
There are many ways to approach this. Consider CountDownLatch:
import java.util.concurrent.CountDownLatch;
public class WorkerTest {
final int NUM_JOBS = 3;
final CountDownLatch countDownLatch = new CountDownLatch(NUM_JOBS);
final Object mutex = new Object();
int workData = 0;
public static void main(String[] args) throws Exception {
WorkerTest workerTest = new WorkerTest();
workerTest.go();
workerTest.awaitAndReportData();
}
private void go() {
for (int i = 0; i < NUM_JOBS; i++) {
final int fI = i;
Thread t = new Thread() {
public void run() {
synchronized(mutex) {
workData++;
}
try {
Thread.sleep(fI * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
}
};
t.start();
}
}
private void awaitAndReportData() throws InterruptedException {
countDownLatch.await();
synchronized(mutex) {
System.out.println("All workers done. workData=" + workData);
}
}
}
Check if all child threads are dead, every n seconds. Simple, yet effective method:
boolean allDead=false;
while(! allDead){
allDead=true;
for (int t = 0; t < threadCount; t++)
if(threads[t].isAlive()) allDead=false;
Thread.sleep(2000);
}

Categories

Resources