Making main thread wait for an event - java

I am doing a college assignment(to be frank enough). The problem is that I should have 4 client threads running at any time (uptil a number n). So, whenver any thread terminates, a new thread must be spawned.
public static void main(String[] args) throws IOException,InterruptedException
{
/* some declarations.. */
ClientThread client=new ClientThread ();
Runnable intr =client;
for(count=1;count<=number;count++)
{
/* If 4 client threads has been spawned, wait until 1 of them exits */
while(Thread.activeCount()<5)
;
new Thread(intr).start();
}
/* Wait until all other threads exits. */
while(Thread.activeCount()!=1)
;
System.out.println("\n The sum of factorials is: "+client.getResult());
}
I want to remove the busy-waiting as it defeats the very purpose of my program. How can i make the main thread wait ?? (It shows wait is a nonstatic method and cannot be invoked from a static method.) Please help.

java.util.concurrent.CountDownLatch is designed for your case.
Define CountDownLatch doneSignal = new CountDownLatch(4);
doneSignal.await() will wait until doneSignal.countDown() is called four times.
So let ClientThreads hold sames reference doneSignal, when run() exits, call doneSignal.countDown().
class ClientThread implements Runnable {
private final CountDownLatch doneSignal;
ClientThread (CountDownLatch doneSignal) {
this.doneSignal = doneSignal;
}
public void run() {
try {
//Do something
doneSignal.countDown();
} catch (InterruptedException ex) {}
}
}
...
//In main thread
doneSignal.await();

Hmm - do you have to do it by hand or does your teacher expect that you discover Executors.newFixedThreadPool(4)?
That's exactly what a thread pool with four worker threads would do: no more then four clients run in parallel, if one terminates, the free'd worker thread is ready to "get a new job".
It's pretty simple:
public void test(int threads, int runnables) {
ExecutorsService pool = Executors.newFixedThreadPool(threads);
Runnable r = new Runnable() {
public void run() {
// calculate a factorial or do something else
System.out.println(Thread.currenThread());
}
}
for (int i = 0; i < runnables; i++)
pool.execute(r);
}
Let runnables be bigger then threads and you'll see from the result that at most threads number of threads are (re-)used to execute the runnables.

You can write a callback method in your main class, that is called by an exiting thread and spawns a new one. By using a static field in the main class you will keep track of the number of threads spawned to obtain the same effect as the current code.
it would look somehow like this :
class Main{
private static ClientThread client;
private static Runnable intr;
private static int count;
public static void main(String[] args)
{
count = 10; //Or something else
runningThreads = 0;
client=new ClientThread ();
intr =client;
for(i=0;i<5;i++)
spawnThread();
}
private static void spawnThread()
{
Thread newThread;
if(count>0)
{
newThread = new Thread(intr);
newThread.start();
count--;
}
if(count==0)
System.out.println("\n The sum of factorials is: "+client.getResult());
}

Take a look # classes in java.util.concurrent
Specifically
java.util.concurrent.CountDownLatch
java.util.concurrent.locks.Condition

For the main thread you can use:
Thread.getCurrent().join();
This will wait for all the spawned threads to die, before the main thread terminates.

Related

How to terminate all other running threads after any of one thread is finish

Problem: I have collection of threads start in a loop parallelly. After exiting anyone of thread first ,all other running threads must be terminated. This is what I tried but it doesn't work. Any help is appreciated.
public class ThreadsMain {
public static void main(String[] args) {
int SIZE = 3;
Thread t[] = new Thread[SIZE];
for (int i = 0; i < SIZE; i++) {
myThreads th = new myThreads();
t[i] = new Thread(th);
t[i].start();
}
}
}
Here is one way to do it, with a synchronizer implemented with intrinsic locks, and using interruption to cancel the unfinished tasks. The data structure makes a consumer thread block until a producer has submitted a result, then it cancels the other worker threads.
This is a toy example, see the link at the end for the real-world way to do this.
First, here's a threadsafe data structure that accepts results, it allows threads to register as listeners and interrupts them once it has a result submitted to it:
class MyQueue<T> {
private java.util.List<T> results = new java.util.ArrayList<T>();
private java.util.List<Thread> listeners = new java.util.ArrayList<Thread>();
public synchronized void put(T o) {
results.add(o);
notifyAll();
for (Thread listener : listeners) {
listener.interrupt();
}
}
public synchronized T take() throws InterruptedException {
while (results.size() == 0) {
wait();
}
return results.remove(0);
}
public synchronized void addListener(Thread t) {
listeners.add(t);
}
}
(I don't like having this class know so much about the listeners but I don't want to overthink a toy example either.)
The wait method releases the lock and makes the calling thread go dormant until a notification occurs (or it can just stop waiting arbitrarily). It uses the size property of the results list to know when a result has been submitted. It's not safe to assume that because a thread stopped waiting that you can infer something about the current state, once the thread reacquires the lock it needs to check what the current state actually is. For more about how wait works see this tutorial.
Here's a task that calculates a result (sleeping between iterations just so these threads can run for a while):
class FibTask implements Runnable {
private final MyQueue<BigInteger> queue;
private final int n;
private long sleepTime;
public FibTask(int n, long sleepTime, MyQueue<BigInteger> queue) {
this.n = n;
this.sleepTime = sleepTime;
this.queue = queue;
}
#Override public void run() {
BigInteger a = BigInteger.valueOf(0);
BigInteger b = BigInteger.valueOf(1);
int i = 0;
try {
while (!Thread.currentThread().isInterrupted() && i < n) {
i = i + 1;
BigInteger temp = a;
a = b;
b = a.add(temp);
Thread.sleep(sleepTime);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
if (!Thread.currentThread().isInterrupted()) {
queue.put(b);
}
}
}
Notice in the code above how the Runnable needs to be aware of attempts to interrupt it. Interruption is cooperative, the task is responsible for deciding when to detect interruption and for handling the termination process.
Also if a task involves IO then in some cases interruption doesn't work and you have to close the socket, see this article for more discussion of this.
Here's the main program that runs the threads and gets the result. The MyQueue class is already doing most of the work so this doesn't have to do much:
class Completion {
public static void main(String ... args) throws Exception {
MyQueue<BigInteger> queue = new MyQueue<BigInteger>();
Thread t1 = new Thread(new FibTask(10, 1000L, queue));
Thread t2 = new Thread(new FibTask(20, 10000L, queue));
Thread t3 = new Thread(new FibTask(25, 50000L, queue));
queue.addListener(t1);
queue.addListener(t2);
queue.addListener(t3);
t1.start();
t2.start();
t3.start();
System.out.println(queue.take());
}
}
Be aware this isn't a fair race because of how the threads' starts are staggered, later threads are at a disadvantage. Submitting tasks to an Executor that initializes a threadpool up front would make sure that the time to start a thread didn't cause a delay here.
For a better way that makes use of java.util.concurrent features like Executors and Futures, see the example given in the API documentation for ExecutorCompletionService.
A simple approach, use a synchronized class to handle the loop condition:
class ThreadHandler
{
static Object lock = new Object();
static boolean finished = false;
static void finishThreads()
{
synchronized(lock)
{
finished = true;
}
}
static boolean isFinished()
{
boolean result;
synchronized(lock)
{
result = finished;
}
return result;
}
}
And in your runnable
class myThreads implements Runnable
{
#Override
public void run()
{
while(!ThreadHandler.isFinished())
{
}
}
}

Thread synchronization with Locks and Conditions

I have a problem to understand Locks and Conditions in Java, i do not understand why my code ends up in a deadlock. My programm consists of a Mainthread and a Subthread, subthread is a member of Mainthread. Both threads run in an infinite loop, Subthread's loop is supposed to execute exactly one iteration as soon as it receives the signal for startCond from the Mainthread. Mainthread should wait for the finishCond signal to continue.
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
public static void main(String[] args) {
LockTest lt = new LockTest();
Mainthread m1 = lt.new Mainthread();
m1.start();
}
public class Mainthread extends Thread {
private Subthread sub = new Subthread();
public void run(){
System.out.println("Main start");
sub.start();
while(!isInterrupted()) {
try {
sub.getStartLock().lock();
sub.getStartCond().signal();
sub.getStartLock().unlock();
sub.getFinishLock().lock();
sub.getFinishCond().await();
sub.getFinishLock().unlock();
System.out.println("Main done");
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Subthread extends Thread {
private Lock startLock = new ReentrantLock();
private Lock finishLock = new ReentrantLock();
private Condition startCond = startLock.newCondition();
private Condition finishCond = finishLock.newCondition();
public Lock getStartLock() {
return startLock;
}
public Lock getFinishLock() {
return finishLock;
}
public Condition getStartCond() {
return startCond;
}
public Condition getFinishCond() {
return finishCond;
}
public void run() {
System.out.println("Sub start");
while(!isInterrupted()) {
try {
startLock.lock();
startCond.await();
startLock.unlock();
finishLock.lock();
finishCond.signal();
finishLock.unlock();
System.out.println("Sub done");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
My expected output would be:
Main done Sub done
(repeated as many times as it was executed in the loops).
Is there a way to solve this problem easier?
The main thread starts, it creates new sub thread and starts it but calling start on a thread does not mean that the thread would receive the processor imeddiatly and that its code will be actually executed.
Main, callss sub.getStartCond().signal(); but at this moment the sub thread is still not running so it misses this signal.
Main, awaits on the finishCond.
Sub starts executing its run method, it goes to the start condition and waits on it for ever.
The deadlock.
Signal wakes up only CURRENTLY waiting thread, it does not 'remember' previous calls.
Use Semaphore instead http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html
it has the semantic of 'counting the permits'.
There might be a more reliable way to do this. I would recommend using a CountDownLatch initialized with a count of 1, instead of a condition. Both the main and child threads can share the same instance of the latch (since the main owns the child that should be easy). The child will call await() and the main will call countDown() when you need to send the signal to the child. I recommend you make the latch private and final.
class ChildThread extends Thread {
private final CountDownLatch signal;
public ChildThread(CountDownLatch signal) {
this.signal = signal;
}
public void run() {
// The loop is necessary in case we get interrupted.
while (true) {
try {
signal.await();
break;
} catch(InterruptedException ignored) {
}
}
// do the work...
}
}
class MainThread extends Thread {
private final ChildThread child;
private final CountDownLatch signalToChild;
public MainThread() {
signalToChild = new CountDownLatch(1);
child = new ChildThread(signalToChild);
}
public void run() {
// I can start the child right away but I'd rather make sure it
// starts if the main thread has started.
child.start();
// prework
// let's signal the child
signalToChild.countDown();
// now the child is working, let's go on with the main thread work
}
}
This works because main and child thread actually share state, i.e., the latch. It does not matter if the main thread decrements the latch before the child thread is actually started, because the child will check this shared state to know if it can start.

LinkedBlockingQueue failing to wait for the threads to execute

I am making a WordCounter, which has several threads counting the words in different files. I have gotten everything to work, except one little issue.
I cannot figure out a proper way to wait for the threads to finish. Everything works if I set a Thread.sleep to wait for a short amount of time, the only problem is that, this will not be a proper solution if the counter takes longer than the sleep does.
import java.io.*;
import java.util.*;
import java.util.concurrent.BlockingQueue;
public class WordCounter implements Runnable{
private String file;
private BlockingQueue<Integer> q;
private int words = 0;
public WordCounter(String f, BlockingQueue<Integer> queue){
file = f;
q = queue;
}
public void run(){
try{
Scanner in = new Scanner(new File(file));
while (in.hasNext()){
in.next();
words++;
}
in.close();
System.out.println(file + ": " + words);
q.add(words);
}
catch (FileNotFoundException e){
System.out.println(file + " blev ikke fundet.");
}
}
}
This is the code from the actual word-counter. I want my main-thread to wait for these word-counter threads to do the q.add(words); function before doing anything else.
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class MainThread implements Runnable{
private String[] arguments;
public MainThread(String[] args){
arguments = args;
}
public void run() {
final BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>();
for(String f : arguments){
WordCounter c = new WordCounter(f, queue);
Thread t = new Thread(c);
t.start();
}
while(!queue.isEmpty()){
try {
System.out.println(queue.take());
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
This is the main-thread. I will need some sort of way to wait for the other threads to finish before I continue to my while statement at the bottom, but how?
Thanks in advance.
Use an ExecutorService and wait on the Future returned. The code below will submit each task to a thread within the executor service (thread pool) and get back the future for that task. When all submitted it will wait on the future. The get method will only return when the run method completes in the task.
public class MainThread implements Runnable{
private String[] arguments;
public MainThread(String[] args){
arguments = args;
}
public void run() {
ExecutorService e = Executors.newFixedThreadPool(arguments.length);
final BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>();
List<Future<?>> tasks = new ArrayList<>();
for(String f : arguments){
tasks.add(e.submit(new WordCounter(f, queue)));
}
for(Future<?> f : tasks) {
f.get();
}
while(!queue.isEmpty()){
try {
System.out.println(queue.take());
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
However
You can make your code cleaner by removing the BlockingQueue entirely and having each task be a Callable<Integer> where it simply returns the words variable. And when you call future.get() the return value there would be the word count.
This is what i would do:
create a counter variable (here is how to do it in a way that is safe for multi-threads) to keep track of how many threads you are spawning in the main
thread
create an interface with function signatures to
increment/decrement that counter
implement that interface in your
main thread
subclass a worker thread to accept that interface as
a parameter
once the worker thread finishes, call that interface
to decrement the number of running threads.
in the implementation of the decrement function on the main thread, add a
condition to do something once the counter is 0.
If you know how many threads to wait on, then you can use a shared semaphore. The worker threads each calls release on the semaphore when they're done; the main thread calls acquire(n) where n is the number of worker threads, which causes the main thread to wait until n permits are available (i.e. until all n worker threads are finished).
You need to keep the created threads in a list and join them from the current thread.
Something like this:
List<Thread> threads = new LinkedList<Thread>();
for (String f : arguments) {
WordCounter c = new WordCounter(f, queue);
Thread t = new Thread(c);
t.start();
threads.add(t);
}
for (Thread t : threads) {
t.join();
}
The join() method will block until the thread terminates.

Why arent the threads running concurrently?

I am running a very simple multi thread program
Main program
package javathread;
public class JavaThread {
public static void main(String[] args)
{
JThread t1 = new JThread(10,1);
JThread t2 = new JThread(10,2);
t1.run();
t2.run();
}
}
JThread.java
package javathread;
import java.util.Random;
public class JThread implements Runnable
{
JThread(int limit , int threadno)
{
t = new Thread();
this.limit = limit;
this.threadno = threadno;
}
public void run()
{
Random generator = new Random();
for (int i=0;i<this.limit;i++)
{
int num = generator.nextInt();
System.out.println("Thread " + threadno + " : The num is " + num );
try
{
Thread.sleep(100);
}
catch (InterruptedException ie)
{
}
}
}
Thread t;
private int limit;
int threadno;
}
I expect both threads to run concurrently/parrallel , something similar to this picture
Instead I am getting this where thread 1 runs first then thread 2 runs
Can someone explain to me why this is happening ??
How do i get the threads to run concurrently ??
Because you called t1.run() and t2.run() instead of t1.start() and t2.start().
If you call run, it's just a normal method call. It doesn't return until it's finished, just like any method. It does not run anything concurrently. There is absolutely nothing special about run.
start is the "magic" method that you call to start another thread and call run in the new thread. (Calling start is also a normal method call, by the way. It's the code inside start that does the magic)
Please go through the Life Cycle of a Thread.
you don't run anything on the Thread, you just run the Runnable (your JThread is NOT a thread, it is just a unnable).
to run on a thread, you need to do something like this:
new Thread(myRunnable).start();
creating the thread in the Runnable does nothing (like you did in JThread constructor).
Because you should start() the Thread, not run() it.

I just wonder why it have to join threads in the second loop

When writing code like:
public class TestBasic {
public static void print(Object o){
System.out.println(o);
}
public static void main(String...strings) throws InterruptedException {
Thread[] threads = new Thread[5];
for(int i=0;i<5;i++){
Thread thread = new Thread(new LittleRunner());
thread.start();
thread.join();
}
}
}
class LittleRunner implements Runnable{
public void run() {
for(int i=1;i<10;i++){
TestBasic.print(Thread.currentThread().getName()+":"+i);
}
}
}
And the output is:
Thread-0:1
Thread-0:2
...
Thread-4:8
Thread-4:9
Which means sequentially printing out. So, does somebody know the reason?
Thanks a lot and Best regards.
You're joining each thread before starting the next thread.
At any single point in time, there will only be one thread running, because you already waited for the previous thread to finish.
You need to start all of the threads before waiting for the first one to finish.
Change the main method to:
public static void main(String...strings) throws InterruptedException {
Thread[] threads = new Thread[5];
for(int i=0;i<5;i++){
threads[i] = new Thread(new LittleRunner());
threads[i].start();
}
for(int i=0;i<5;i++){
threads[i].join;
}
}
Basically, thread.start() will start the thread in background and move on. Then, when you do a thread.join(), the execution will stop until thread is finished. So, in your version of the program, you were starting each thread and then waiting for it to finish before starting the next thread, hence the sequential execution.

Categories

Resources