Facing Issue in Join method in thread - java

I have a doubt that I am creating few threads inside a loop and it will call the run method that I had implemented . I have doubt that though I have written t.join without completing its run method main thread is moving forward and executing later steps. How to stop this ?
for(int j=1;j<=iteration;j++){
Thread t=null;
System.out.println("Starting Iteration-"+j);
for(int i=1;i<=totalNumberOfUsers;i++) {
t=new Thread(new CasLoadTest());
t.setName("User"+i);
t.start();
Thread.sleep((long) (delayPeriod*1000));
}
t.join();
for(Map.Entry<String,Long> map:latencyMap.entrySet()){
System.out.println(map.getKey()+"-"+map.getValue());
}
System.out.println("Iteration"+j+"-->Max:"+Collections.max(latencyMap.values()));
System.out.println("Iteration"+j+"-->Min:"+Collections.min(latencyMap.values()));
double temp=(double)(lastUserLoggedIn-firstUserLoggedIn)/1000;
System.out.println("Iteration"+j+"-->Total Number of Users Logged In (Users\\Sec)--"+totalNumberOfUsers/temp);
latencyMap.clear();
threadCount = totalNumberOfUsers;
count = 0;
Thread.sleep(30000);
}

Collect all Threads that you have created in a list. Then you can wait for all to exit their operation before going on with your main method.
ArrayList<Thread> allThreads = new ArrayList<>(); // create a list of all Threads
for(int i=1;i<=totalNumberOfUsers;i++) {
t=new Thread(new CasLoadTest());
allThreads.add(t); // add new Thread to list
...
}
...
// wait for all Threads to end before executing next code
for(Thread thread : allThreads)
thread.join();

Related

Awaiting pool to finish threads

StopWatch sw = new StopWatch();
sw.start();
ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS);
for (int i = 0; i < MYTHREADS; i++) {
Runnable worker = new SingleConnectionRunnable();
executor.execute(worker);
}
sw.stop();
System.out.println("total time"+sw.toString());
sw.reset();
sw.start();
for (int i = 0; i < MYTHREADS; i++) {
Runnable worker2 = new PooledConnectionRunnable();
executor.execute(worker2);
}
executor.shutdown();
executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
while (!executor.isTerminated()) {
}
sw.stop();
System.out.println("total time"+sw.toString());
I am trying to run some perf tests on the code above. I am trying to use the same executor on different Runnable and measure the time. But it doesn't quite work. the first "total time" is not correct which is in milliseconds.
I want to print the elapsed time on the first loop then print the second loop. Not sure how I can wait executor to finish the first one then restart the executor.
What is the correct way to get this done?
First, awaitTermination will block until all tasks terminate. Is there any particular reason that you use a while loop check after waiting potentially 70 years?
Anyways, to answer your question, in order to wait for the first run to finish, you should use a CountDownLatch to signal completion of each thread and await for them in the main thread until they finish. You can also use a CyclicBarrier to await until all your threads are ready to go before starting timing, like so:
...
CountDownLatch latch = new CountDownLatch(MYTHREADS);
CyclicBarrier cb = new CyclicBarrier(MYTHREADS, new Runnable() {
#Override public void run() {
sw.start();
}
});
for (...) {
Runnable worker = ...
executor.execute(new Runnable() {
#Override public void run() {
try {
cb.await();
} catch (Exception e) {
throw new RuntimeException(e);
}
worker.run();
latch.countDown();
}
});
}
latch.await();
sw.stop();
...
I moved the sw.start() to the beginning of the for-loop to avoid measuring object allocation overhead to setup (probably won't be measured anyways since its in ms).
You can also reset the two concurrency classes to run an indefinite number of times.
What you are doing now is:
Start the stopwatch
Start a few threads
Read the stopwatch
You are not waiting for them to finish like you do with the second loop.
This is what you can do to fix this.
Make a callback method in the SingleConnectionRunnable.
This method will be called at the last point of this runnable (when you terminate it) and caught by the class that starts the loop (which is not method in the question but that is fine).
In this callback method you keep track of how many times it is called.
When it is called MYTHREAD amount of times you print the stopwatch time.
Now you know how long it will take until all started threads are finished.

Java Threading: Is using interrupt() within run() acceptable to stop a thread when it is finished completing its task?

I have setup a Java Thread class which preforms a particular task of creating a new Process and running it along with various other things.
In the parent class which invokes the Thread I have setup a loop
while(!thread.isActive()) {
...
}
I wanted to know if it is best practices / acceptable to update the run() in the Thread class to issue a interrupt()
run() {
callTask();
interrupt();
}
Update
I could then create a boolean finished field on the Thread and change that to true once the callTask() is completed and have the parent look for
Thread:
run() {
callTask();
finished = true;
}
Parent:
// Start the threads for each Device
for (DeviceRunner deviceRunner : deviceRunners) {
deviceRunner.start();
}
boolean doneProcessingDevices = false;
while (!doneProcessingDevices) {
Set<DeviceRunner> deviceRunnersToRemove = new HashSet<DeviceRunner>();
for (DeviceRunner deviceRunner : deviceRunners) {
if (deviceRunner.isFinishedRunning()) { // check to see if the thread is finished
deviceRunnersToRemove.add(deviceRunner);
}
}
// remove the device runners which are no longer active
deviceRunners.removeAll(deviceRunnersToRemove);
if (deviceRunners.isEmpty()) {
doneProcessingDevices = true;
}
Thread.sleep(1000);
}
Thank you
Just to clarify: you don't have to stop threads manually. When run() completes, the native thread will die and the Thread object will be garbage collected.
If you want your parent to wait until all tasks completed, you can use a CountDownLatch. Initialize the latch with the number of tasks that have to be done. Every time a task finishes, let him invoke countDown(). In the meantime, your parent blocks on await():
Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted.
This MWE demonstrates the basic idea:
int numberOfTasks = 3;
CountDownLatch latch = new CountDownLatch(numberOfTasks);
while (numberOfTasks-- > 0) {
new Thread(() -> {
try {
// Do stuff.
System.out.println("Done.");
} finally {
latch.countDown();
}
}).start();
}
try {
latch.await();
System.out.println("All tasks finished.");
} catch (InterruptedException e) { /* NOP */ }
You won't see All tasks finished. before each task has printed Done..
I believe what you are really looking for is Thread.join method. Copying from Oracle tutorial
The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing, t.join()
causes the current thread to pause execution until t's thread terminates

Thread does not stop after interruption

I have a problem that a threads do not stop after I call .interrupt() method. There is a code snippet
for (Thread t : letters.getThreads()) t.start();
Thread.sleep(5000);
for (Thread t : letters.getThreads()) t.interrupt();
There getThreads() method is from class Letters (letters is an object of the class) and it returns array of Thread objects. Here you have body of the method from Letters class:
public Thread[] getThreads() {
Thread[] threads = new Thread[letters.length];
for(int i = 0; i < threads.length; i++) {
threads[i] = new Thread( () -> {
while(true) {
try {
System.out.print("a");
Thread.sleep(1000);
} catch (InterruptedException ex) {
return;
}
}
}
,"Thread " + letters[i]); //letters[] is a local array.
}
return threads;
}
and in this case I described, threads do not stop working, but when I do everything in main mathod ( array of Threads objects ) it works properly. Why is this happening?
In the getThreads() method, you create new threads. First call create new threads and started them. However the 2nd call also create new threads but never started hence interrupt non-running threads doesn't work?

limit maximum threads executing at time in java

Trying to figure out how threading in Java works, i just want to limit runnable threads executing by putting them all to array and then check in loop if some of them finished and pop them out, to have possibility to spawn a new thread, got exception in this code:
public class testThread implements Runnable {
public void run () {
try {
Thread.sleep(1000);
} catch(InterruptedException e){}
System.out.println("This is the test thread");
}
public static void main (String args[]) {
int max_threads = 5;
Thread worker;
ArrayList<Thread> all_workers = new ArrayList<Thread>(max_threads );
for (int i =0; i<50; i++) {
if (all_workers.size()<max_threads){
worker = new Thread (new testThread());
all_workers.add(worker);
worker.start();
} else{
System.out.println("i ran all");
while(all_workers.size()>=max_threads){
try{
System.out.println("Waiting for some to finish");
int counter = 0;
for (Thread wrk: all_workers){
if (!wrk.isAlive()){
all_workers.remove(counter);
}
counter ++ ;
}
Thread.sleep(500);
} catch (InterruptedException e){
System.out.println("Catched unhandled ");
}
}
}
}
for(Thread wrk: all_workers){
try {
wrk.join();
} catch (InterruptedException e) {
}
}
}
}
exception i got when i run it:
anybody#anymachine ~/java $ java testThread
i ran all
Waiting for some to finish
Waiting for some to finish
This is the test thread
This is the test thread
This is the test thread
This is the test thread
This is the test thread
Waiting for some to finish
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at testThread.main(testThread.java:39)
thank you for any help, if there is a good tutorial i would be much appriciated for link.
PS. if there is any debugger in java like pdb in python please let me know.
thank you!
You should have a look at the higher level threading utilities like ExecutorService and ThreadPools.
You should never terminate a thread manually and I suggest to avoid manual thread creation/management in general.
If you want to wait for a number of threads finishing, you may want to use a CountDownLatch.
Here is an example.
Exception in thread "main" java.util.ConcurrentModificationException
You are getting this because you are removing from an ArrayList while you are iterating across it. This is not allowed.
for (Thread wrk : all_workers) {
if (!wrk.isAlive()) {
// ERROR, you can't change the collection while you are in a for loop
all_workers.remove(counter);
}
...
If you need to remove from a list you are walking across, you should use the iterator.remove() instead:
Iterator<Thread> iterator = all_workers.iterator();
while (interator.hasNext()) {
Thread wrk = interator.next();
if (!wrk.isAlive()) {
// this is allowed because you are using the iterator directly
iterator.remove();
}
}
A better solution to your specific situation is to use the ExecutorService code. What you do then is to create a fixed thread pool and submit your jobs to it:
// create a thread pool with 5 worker threads
ExecutorService threadPool = Executors.newFixedThreadPool(5);
// define your jobs somehow
for (int i = 0; i < 50; i++) {
threadPool.submit(new testThread());
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
// then wait for it to complete
threadPool.awaitTermination(Long.MAX_LONG, TimeUnit.MILLISECONDS);
First, why do you need to limit the number of running threads? Note, computer cannot simultaneously run more threads than it has processors anyway.
The main drawback of your solution is Thread.sleep(500). It causes unnecessary latency.
The right solution is to use a java.util.Executor with desired number of threads. Then you simply call executor.execute(new testThread()) instead of new Thread (new testThread()).start().
Change the below line
ArrayList<Thread> all_workers = new ArrayList<Thread>(max_threads);
To
Set<Thread> all_workers = Collections.newSetFromMap(new ConcurrentHashMap<Thread,Boolean>())

Is it possible to call Thread start() and join() in a single call?

I'm playing with threads in Java and i have a question about the join() method.
Let's say i have a SampleClass that extends Thread. I instantiate some new threads in the main but i want the thread's job to be completed sequentially using join().
public static void main(String[] args) {
for(int i=0; i<5; i++){
new SampleClass().start();
}
}
Is it possible to call immediately join()? ...something like this:
new SampleClass().start().join();
Or is there another approach to use? ...like this maybe:
new SampleClass().start();
try{Thread.currentThread().join();}catch(InterruptedException e){...}
Thank you very much
new SampleClass().start().join(); This is wrong.
You can achieve similar thing by
SampleClass samClass = new SampleClass();
samClass.start();
samClass.join()
The above code will have same effect as you wanted.
Now your problem is to run the Threads Sequentially. In most of these
cases you don't need threads to execute sequentially (But yes there are some scenarios).
Well If you do have to.
Then you can Do Like this
Thread t1 = ..
Thread t2 = ..
t1.start();
t1.join();
t2.start(); // t2 will start only when t1 dies
t2.join(); //
t3.start(); // t3 will start only when t2 dies..
But the above approach is not good. Because for other thread to start, previous thread
needs to die. In practice We should think of creating threads as an expensive operation
and try to reuse.
The real problem often is like this, You have to execute tasks T1 , T2 , T3 , T4
sequentially but in different Threads T1 && T3 have to run on one threads and T2 and T4
have to run on another.
So here we can use Two threads instead of 4.
Thread1 will run T1 and then Thread2 will run T2 and then Thread1 will run T3 and so on
i.e.
Thread1 -> T1
Thread2 -> T2
Thread1 -> T3
Thread2 -> T4
All task will be executed sequentially but using 2 threads only.
You can solve the problem like below
Thread1 ->run {
while(canIrun) {
executeTask(taskQueue1.next());
notifyThread2();
waitForThread2Signal();
}
}
Thread2 -.run {
while(canIrun) {
waitForThread1Signal();
executeTask(taskQueue2.next());
notifyThread1();
}
}
The wait and notify method can be implemented using CyclicBarrier very easily.
What would be the point? You can get the same effect, without the overhead, by just calling run().
You can use ExecutorService#submit(Runnable runnable).get()
Is it possible to call immediately join()?
No it is not as start() returns void . You cannot chain those methods that way. And you need to invoke join() on a Thread object.
Method start belongs to Thread class. It would be like doing this:
Thread thread = new Thread(someRunnableTask);
//This fails to compile, because start returns NOTHING (void). This variable will not be filled with pointer to our thread object.
Thread ourOriginalThreadPointer = thread.start();
//Hence this variable references to nothing, no method can be called.
ourOriginalThreadPointer.join()
The instanciated thread doesn't need to be anonymous. You can do that:
public static void main(String[] args) {
for(int i=0; i<5; i++){
SampleClass sc = new SampleClass();
sc.start();
try {
sc.join();
} catch (InterruptedException e) {
}
}
}

Categories

Resources