Thread does not stop after interruption - java

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?

Related

How to run a task once every Threads finished running in Java?

I have a loop which create a new Thread on each iteration, like so:
for(int i = 0; i < REPEAT; i++) {
new Thread(new MyTask(i)).start();
Thread.sleep(1);
}
private void finalTask() {
//Some code to be executed once every threads stopped running
}
Where MyTask is a class implementing Runnable. My goal is: I would like to run finalTask once every threads stopped. To achieve this, I have tried incrementing a variable by 1 each time a thread finished running, and once this variable was equal to REPEAT, the final task would run. But this didn't work. I've searched on Google and StackOverlow for answers to my problem, but there are very little informations on this and none of them worked as well. There would always be a thread that was running after the final task. How can I do this then?
You can use a CountDownLatch for this. A CountDownLatch is
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
CountDownLatch countDownLatch = new CountDownLatch(REPEAT);
for (int i = 0; i < REPEAT; i++) {
new Thread(new MyTask(i, countDownLatch)).start();
Thread.sleep(1);
}
finalTask(countDownLatch);
I create a CountDownLatch whose count is initialized to the value of REPEAT. I pass this to each of the threads and to the finalTask method.
Each thread after doing its work should call the countDown method of the countDownLatch.
private static class MyTask implements Runnable {
private int i;
private CountDownLatch countDownLatch;
private MyTask(int i, CountDownLatch countDownLatch) {
this.i = i;
this.countDownLatch = countDownLatch;
}
#Override
public void run() {
//Perform some task
System.out.println("Running " + i);
countDownLatch.countDown();
}
}
The first line of the finalTask method should call the await method of the CountDownLatch. This will cause the thread running the finalTask wait till the count of the CountDownLatch reaches 0 i.e., until all threads (REPEAT number of them) has completed and invoked the countDown of the CountDownLatch.
private static void finalTask(CountDownLatch countDownLatch) {
try {
countDownLatch.await(); //this will wait until the count becomes 0.
} catch (InterruptedException e) {
e.printStackTrace(); //handle it appropriately
}
//Some code to be executed once all threads stopped running
System.out.println("All done");
}
Another simple way is to just join() on all the threads and then call finalTask():
Thread tasks[] = new Thread[REPEAT];
for(int i = 0; i < REPEAT; i++) {
tasks[i] = new Thread(new MyTask(i));
tasks[i].start();
}
for (Thread task : tasks) {
for (;;) {
try {
task.join();
break;
}
catch ( InterruptedException e ) {
// catch code here
}
}
}
finalTask();
Note there's almost more code used to handle the possible InterruptedException from the join() method call than used to implement the rest of the processing.
You can put them into CompletableFutures and then use whenComplete() .
CompletableFuture[] all =
IntStream.range(0, REPEAT+1).
.mapToObj(i -> CompletableFuture.supplyAsync(new MyTask(i)))
.toArray(CompletableFuture[]::new) ;
CompletableFuture.allOf(all).whenComplete((r, t) -> {
// your code here
}) ;

Custom Way to Wait for all thread to complete in Java?

After Starting the thread object
thread1.start();
thread2.start();
i need to wait for the finalization of both threads using the join() method(the most common way).
Like this.
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
All the tutorial i see uses some inbuilt method for finalization of threads.
Is there a way to wait for thread finalization without using any inbuilt method like join or executor ?
Every Thread has a state. NEW , RUNNABLE , BLOCKED , WAITING , TIMED_WAITING , or
TERMINATED
TERMINATED is a state that you can look for every thread with thread.getState() method, which is the state of thread once it finish execution
// 2 Thread Object
Thread threads[] = new Thread[2];
// store Thread Statuses
Thread.State status[] = new Thread.State[2];
Since All Thread have state. Before starting thread store
their state
for (int i = 0; i < 2; i++) {
status[i] = threads[i].getState();
}
Once you start the thread
The finished Thread has a state of Terminated, you can use it to
and write your own check for finalization
// custom way for finalization of the threads
boolean finish = false; // initially all non finised
while(!finish) {
for (int i = 0; i < 2; i++) {
if (threads[i].getState() != status[i]) {
status[i] = threads[i].getState();
}
}
finish = true;
for (int i = 0; i < 2; i++) {
finish = finish && (threads[i].getState() ==
State.TERMINATED);
}
}

Can anyone explain this program? We cannot start a thread twice but we are getting an output 1-20.. can anyone explain?

import java.io.IOException;
public class Test implements Runnable {
private int m, n;
public synchronized void run() {
try {
for (int i = 0; i < 10; i++) {
m++;
n++;
Thread.sleep(100);
System.out.println(m + ", " + n);
}
} catch (InterruptedException e) {
}
}
public static void main(String[] args) {
try {
Test a = new Test();
new Thread(a).start();
new Thread(a).start();
} catch (Exception e) {
}
}
}
You are correct that you cannot start the same thread twice. But you aren't doing that here. You are starting two separate threads once each.
Your code is essentially the same as:
Thread t1 = new Thread(a);
t1.start();
Thread t2 = new Thread(a);
t2.start();
You are declaring 2 different threads and running them one after another. If you add the following code.
public synchronized void run() {
System.out.println("thread started");
try {
for (int i = 0; i < 10; i++) {
m++;
n++;
Thread.sleep(100);
System.out.println(m + ", " + n);
}
} catch (InterruptedException e) {
}
System.out.println("thread fininshed");
}
You can easily see where the first thread ends and then the second thread starts.
Each of your threads needs to execute task described in instance of Test class. More precisely in its run method. In your case both threads will need to execute task of Test but they will also need to use same instance of this class (which is stored in a reference).
Problem is that run method is synchronized which means it uses monitor/lock of current instance (this - available via a reference) which means that both threads can't execute it at the same time. To be more precise one of threads will need to wait until other thread will finish execution code from that synchronized block (which is entire body of run).
So in your case
one of your threads will print
enter synchronized block locked on a
print values in range 1-10
exit synchronized block locked on a
so now another thread can
enter synchronized block locked on a
print values in range 11-20 (since m and n will be increased each time in loop)
exit synchronized block locked on a

Facing Issue in Join method in thread

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();

Thread Synchronization - Synchronizing three threads to print 012012012012..... not working

I am trying to synchronize three threads to print 012012012012.... but it is not working correctly. Each thread is assigned a number which it prints when it receives a signal from main thread. There is something wrong with the following program which I am not able to catch.
public class Application {
public static void main(String[] args) {
int totalThreads = 3;
Thread[] threads = new Thread[totalThreads];
for (int i = 0; i < threads.length; i++) {
threads[i] = new MyThread(i);
threads[i].start();
}
int threadIndex = 0;
while (true) {
synchronized(threads[threadIndex]) {
threads[threadIndex].notify();
}
threadIndex++;
if (threadIndex == totalThreads) {
threadIndex = 0;
}
}
}
}
class MyThread extends Thread {
private int i;
public MyThread(int i) {
this.i = i;
}
#Override
public void run() {
while (true) {
synchronized(this) {
waitForSignal();
System.out.println(i);
}
}
}
private void waitForSignal() {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
You need more coordination. the notify call does not immediately wake up the thread and force it to proceed. Instead, think of notify as sending an email to the thread to let it know that it can proceed. Imagine if you wanted your 3 friends to call you in order. You sent friend 1 an email to call you, waited one second, sent an email to friend 2, waited a second, and sent an email to friend 3. do you think you'd get called in that exact order?
one way to add more coordination would be to have some shared state which indicates whose turn it is. if all your friends could see your house, you could put a number on the outside of the house indicating whose turn it was to call. each friend would wait until they saw their number, and then call.
Here's your problem:
int threadIndex = 0;
while (true) {
synchronized(threads[threadIndex]) {
threads[threadIndex].notify();
}
threadIndex++;
if (threadIndex == totalThreads) {
threadIndex = 0;
}
}
The main thread notifies all threads in the right order. However, your threads are working independently. They may or may not get scheduled at a specific point in time. So the end result may be, that thread 2 is reaching the wait/print lock before thread 1 before thread 0. The final order is not determined by you sending the notifications, but (in essence) by the scheduler.
The solution is to change it this way:
the main thread notifies exactly one thread: thread 0
every thread does his work and when done, notifies the next thread in line
obviously the last thread has to notify thread 0 again.
Another possible solution: In the main thread, you can wait immediately after having notified a thread (in the same synchronized block), like this:
synchronized (threads[threadIndex])
{
threads[threadIndex].notify();
threads[threadIndex].wait(); // try/catch here
}
And in the run method of the thread, you can use notifyAll to wake up the main thread after the thread finished its work:
synchronized (this)
{
waitForSignal();
System.out.println(i);
notifyAll();
}
More sophisticated solutions would involve classes from the java.util.concurrent.locks package.
package threads;
import java.util.concurrent.Semaphore;
public class ZeroEvenOddPrinter {
class Runner extends Thread{
Semaphore prev;
Semaphore next;
int num = 0;
public Runner(Semaphore prev,Semaphore next,int num){
this.prev = prev;
this.next = next;
this.num = num;
}
#Override
public void run(){
while (true) {
try {
Thread.sleep(100);
prev.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (num == 0)
System.out.println(0);
else {
System.out.println(num);
num = num + 2;
}
next.release();
}
}
}
static public void main(String args[]) throws InterruptedException{
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(1);
Semaphore sem3 = new Semaphore(1);
ZeroEvenOddPrinter zeo = new ZeroEvenOddPrinter();
Runner t1 = zeo.new Runner(sem1,sem2,0);
Runner t2 = zeo.new Runner(sem2,sem3,1);
Runner t3 = zeo.new Runner(sem3,sem1,2);
sem1.acquire();
sem2.acquire();
sem3.acquire();
t1.start();
t2.start();
t3.start();
sem1.release();
}
}
Here i am using semaphores as triggers for all the three threads. Initially all threads will be blocked on sem1,sem2,sem3. Then i will release the sem1 and first thread will execute then it will release the second thread and so on... The best part is you extend this logic to n number of threads. Good Luck!!!

Categories

Resources