I have two classes. In class A, I have the run() method looped forever, while in the class B, i have the threadpool.
My question is, From Class B, how can I control and stop the thread executing run() method in class A , I have tried forceshutdown, threadExecutor.shutdownNow(), But it isnt working.
The loop seems to go on forever.
Here is example piece of code:
public class A implements Runnable {
public void run() {
while (true) {
System.out.println("Hi");
}
}
}
public class B {
public static void main(String[] args) {
int noOfThreads = 1;
A ThreadTaskOne = new A();
System.out.println("Threads are being started from Class B");
ExecutorService threadExecutor = Executors.newFixedThreadPool(noOfThreads);
threadExecutor.execute(ThreadTaskOne);
threadExecutor.shutdownNow();
System.out.println("B Ends, no of threads that are alive : " + Thread.activeCount());
}
}
As #MadProgammer said, your "infinite" loop needs to pay attention to Thread.isInterrupted. e.g. (very schematic)
public void run() {
while (!Thread.isInterrupted()) {
doSomethinginTheLoop1();
blah...blah...blah
// if the loop is very long you might want to check isInterrupted
// multiple times for quicker termination response
doSomethingInTheLoop2();
}
// now, here's a decision of what you do
// do you throw an InterruptedException or trust others to check interrupted flag.
// read Java COncurrency in Practice or similar...
}
The documentation on ExecutorService#shutdownNow() says -
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
And your thread doesn't seem to care if it has been interrupted.
So check if it has been interrupted
while (Thread.currentThread().isInterrupted())
instead of just doing
while (true)
May be below is useful for you.
public static class A implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("Hi");
}
}
}
Related
In my applications there are an n number of actions that must happen, one after the other in sequence, for the whole life of the program. Instead of creating methods which implement those actions and calling them in order in a while(true) loop, I decided to create one thread for each action, and make them execute their run method once, then wait until all the other threads have done the same, wait for its turn, and re-execute again, and so on...
To implement this mechanism I created a class called StatusHolder, which has a single field called threadTurn (which signifies which thread should execute), a method to read this value, and one for updating it. (Note, this class uses the Singleton design pattern)
package Test;
public class StatusHolder
{
private static volatile StatusHolder statusHolderInstance = null;
public static volatile int threadTurn = 0;
public synchronized static int getTurn()
{
return threadTurn;
}
public synchronized static void nextTurn()
{
System.out.print("Thread turn: " + threadTurn + " --> ");
if (threadTurn == 1)
{
threadTurn = 0;
}
else
{
threadTurn++;
}
System.out.println(threadTurn);
//Wake up all Threads waiting on this obj for the right turn to come
synchronized (getStatusHolder())
{
getStatusHolder().notifyAll();
}
}
public static synchronized StatusHolder getStatusHolder()
{//Returns reference to this object
if (statusHolderInstance == null)
{
statusHolderInstance = new StatusHolder();
}
return statusHolderInstance;
}
}
Then I have, let's say, two threads which must be execute in the way explained above, t1 and t2.
T1 class looks like this:
package Test;
public class ThreadOne implements Runnable
{
#Override
public void run()
{
while (true)
{
ThreadUtils.waitForTurn(0);
//Execute job, code's not here for simplicity
System.out.println("T1 executed");
StatusHolder.nextTurn();
}
}
}
And T2 its the same, just change 0 to 1 in waitForTurn(0) and T1 to T2 in the print statement.
And my main is the following:
package Test;
public class Main
{
public static void main(String[] args) throws InterruptedException
{
Thread t1 = new Thread(new ThreadOne());
Thread t2 = new Thread(new ThreadTwo());
t1.start();
t2.start();
}
}
So the run method goes like this:
At the start of the loop the thread looks if it can act by checking the turn value with the waitForTurn() call:
package Test;
public class ThreadUtils
{
public static void waitForTurn(int codeNumber)
{ //Wait until turn value is equal to the given number
synchronized (StatusHolder.getStatusHolder())
{
while (StatusHolder.getTurn() != codeNumber)
{
try
{
StatusHolder.getStatusHolder().wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
If the two values are equal, the thread executes, otherwise it waits on the StatusHolder object to be awaken from the nextTurn() call, because when the turn value changes all the threads are awaken so that they can check if the new turn value is the one they are waiting for so they can run.
Note thatnextTurn() cycles between 0 and 1: that is because in this scenario I just have two threads, the first executes when the turn flag is 0, and the second when its 1, and then 0 again and so on. I can easily change the number of turns by changing this value.
The problem: If I run it, all goes well and seems to work, but suddenly the output console stops flowing, even if the program doesn't crash at all. I tried to put a t1.join() and then a print in the main but that print never executes, this means that the threads never stop/dies, but instead they remain locked sometimes.
This looks to be even more evident if I put three threads: it stops even sooner than with two threads.
I'm relatively new to threads, so I might be missing something really stupid here...
EDIT: I'd prefer not to delete a thread and create a new one every time: creating and deleting thousands of objs every second seems a big work load for the garbage collector.
The reason why I'm using threads and not functions is because in my real application (this code is just simplified) at a certain turn there actually are multiple threads that must run (in parallel), for example: turn 1 one thread, turn 2 one thread, turn 3 30 threads, repeat. So I thought why not creating threads also for the single functions and make the whole think sequential.
This is a bad approach. Multiple threads allow you to execute tasks concurrently. Executing actions "one after the other in sequence" is a job for a single thread.
Just do something like this:
List<Runnable> tasks = new ArrayList<>();
tasks.add(new ThreadOne()); /* Pick better names for tasks */
tasks.add(new ThreadTwo());
...
ExecutorService worker = Executors.newSingleThreadExecutor();
worker.submit(() -> {
while (!Thread.interrupted())
tasks.forEach(Runnable::run);
});
worker.shutdown();
Call worker.shutdownNow() when your application is cleanly exiting to stop these tasks at the end of their cycle.
you can use Semaphore class it's more simple
class t1 :
public class t1 implements Runnable{
private Semaphore s2;
private Semaphore s1;
public t1(Semaphore s1,Semaphore s2){
this.s1=s1;
this.s2=s2;
}
public void run()
{
while (true)
{
try {
s1.acquire();
} catch (InterruptedException ex) {
Logger.getLogger(t1.class.getName()).log(Level.SEVERE, null, ex);
}
//Execute job, code's not here for simplicity
System.out.println("T1 executed");
s2.release();
}
}
}
class t2:
public class t2 implements Runnable{
private Semaphore s2;
private Semaphore s1;
public t2(Semaphore s1,Semaphore s2){
this.s1=s1;
this.s2=s2;
}
public void run()
{
while (true)
{
try {
s2.acquire();
} catch (InterruptedException ex) {
Logger.getLogger(t2.class.getName()).log(Level.SEVERE, null, ex);
}
//Execute job, code's not here for simplicity
System.out.println("T2 executed");
s1.release();
}
}
}
class main:
public class Testing {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Semaphore s2=new Semaphore(0);
Semaphore s1=new Semaphore(1);
Thread th1 = new Thread(new t1(s1,s2));
Thread th2 = new Thread(new t2(s1,s2));
th1.start();
th2.start();
}}
LockSupport.upark() can occur before LockSupport.park() method but in the follow code why it block the code.in my code ,in the main thread there are 4 LockSupport.unpark(t1),actually,it can obtain only one access,when i run the thread t1,LockSupport.park() can consume one and return,but it block the code ,Why?
public class LockSupportDemo{
public static Object u = new Object();
static ChangeObjectThread t1 = new ChangeObjectThread("t1");
public static class ChangeObjectThread extends Thread{
public ChangeObjectThread(String name)
{
super.setName(name);
}
#Override
public void run() {
synchronized (u)
{
LockSupport.park(Thread.currentThread());
System.out.println("in "+ getName());
if(Thread.interrupted())
{
System.out.println(getName()+" interrupted");
}
}
System.out.println(getName() +"isOver");
}
}
public static void main(String[] args) throws InterruptedException {
LockSupport.unpark(t1);
LockSupport.unpark(t1);
LockSupport.unpark(t1);
LockSupport.unpark(t1);
LockSupport.unpark(t1);
t1.start();
}
}
The Javadoc for LockSupport.unpark is very explicit on this:
Makes available the permit for the given thread, if it was not already
available. If the thread was blocked on park then it will unblock.
Otherwise, its next call to park is guaranteed not to block. This
operation is not guaranteed to have any effect at all if the given
thread has not been started.
What you did above can't work.
To achieve the same, you could start the thread but have it wait until you call unpark in the main thread, by using wait/notify signalling, for example. Or if you needed something quick and dirty (since this seems to be more about exploring LockSupport than about writing production code), then you could even use Thread.sleep(1000); at the start of the run method.
I have a program which creates 10 threads, and each thread has an infinitely running while loop.
I need help to efficiently implement a Shutdown hook which can effectively STOP all the threads. Since I want to do a graceful shutdown each Thread should finish as soon as it finds the stop flag turned to TRUE.
public class SampleGSH implements Runnable{
private static boolean stop = false;
public static void main(String[] args) {
for(int i = 0; i < 10;i++) {
Thread t = new Thread(new SampleGSH(), "name"+i);
t.start();
}
}
#Override
public void run() {
Runtime.getRuntime().addShutdownHook(new Thread("shutdown thread") {
public void run()
{
System.out.println("*******");
synchronized (this)
{
System.out.println("Turning switch off");
stop = true;
}
}
});
synchronized (this) {
while(!stop)
{
//Some logic which should not be killed abruptly once it starts running, a graceful shut down will not allow this code to start
}
}
}
}
Any help will be truly appreciated.
I need help to efficiently implement a Shutdown hook which can effectively STOP all the threads.
If you have any fields that are shared between multiple threads, they need to be synchronized. In this case your stop should be volatile. Without this, there is nothing that ensures that the threads will see the value of stop change to true. See this tutorial for information about atomic access.
See: Using boolean var for stopping threads
Couple other comments:
If you are starting a number of threads, you should consider using an ExecutorService
Your while loop is inside of a synchronized block. This does nothing and the stop field will not get memory synchronized since it gets updated externally while inside of the block.
Another way to stop a thread would be to interrupt() it. See this tutorial.
while (!thread.currentThread().isInterrupted()) {
...
}
...
t.interrupt();
Instead of a single static stop boolean, you could give every thread its own stop boolean. Then store all thread objects when creating them and set their stop boolean to true in the shutdown hook thread (which would be hooked in the main method).
Something like this:
import java.util.ArrayList;
import java.util.List;
public class SampleGSH extends Thread {
public boolean stop = false;
private static List<SampleGSH> threads = null;
public static void main(String[] args) {
threads = new ArrayList<SampleGSH>();
int numThreads = 10;
for (int i = 0; i < numThreads; i++) {
SampleGSH t = new SampleGSH();
threads.add(t);
t.start();
}
Runtime.getRuntime().addShutdownHook(new Thread("shutdown thread") {
public void run() {
System.out.println("*******");
for (SampleGSH t : threads) {
t.stop = true;
}
}
});
}
#Override
public void run() {
{
while (!stop) {
// Some logic which should not be killed abruptly once it starts
// running, a graceful shut down will not allow this code to
// start
}
}
}
}
Forget that addShutdownHook guff ... keep it simple ...
Make the static stop variable volatile ...
then add this method to SampleGSH ...
public void shutdown() {
stop = true;
}
then call it when you want to stop the threads!
if i have got such java code:
public static void main(String[] args)
{
for(int i = 0;i<100;i++)
{
Future<?> f = ThreadPoolManager.getInstance().schedule(new START(), 500);
f.cancel(true);
}
}
private class START implements Runnable
{
#Override
public void run()
{
System.out.println(1);
}
}
And run it in debug, i can see that all of those threads(after cancel) are still running, so are they taking my memory too? And if yes, how can i destroy those Threads completely?
cancel(true) calls interrupt() on your thread, nothing more. So, you need to handle it properly in your run() method. For your simple case your threads will finish their execution and their objects will be cleared by GC.
I have written a program to understand wait() and notify() methods. But when I run the program it hangs and nothing happens. Basically I want one thread (ThreadDemo) to complete its execution (display its output) thereafter other thread should display its output (ThreadDemo2).
As wait and notify requires the use of same object I have created common class LogicClass.
Can you please point out what is the problem in my code? I have to use these concepts in my project.
Program Link
In the code, I noted at least two problems:
Your main function does not wait for the child threads to join and so will exit. Use Thread::join.
You never call show() function that includes the notifyAll.
Pretty sure that non-daemon threads will not exit when the main thread exits.
I'd recommend using java.util.concurrent package if at all possible. It makes multithreading less error prone. You are missing for example a missed notification guard that can cause eternal waiting. If you were to use a latch it would solve that problem.
** EDIT
Sorry I should say your existing missed notification guard (value in LogicClass) can have cases where it doesn't function correctly - the while loops before the wait or notify aren't sufficient to guarantee which thread "wins the race" to the monitor.
I made a comment earlier about making the code shorter while still demonstrating the same behaviour. You can see one thread is running show, the other display
class ThreadMain {
public static void main(String[] args) {
final LogicClass lg = new LogicClass(true);
new Thread(new Runnable() {
public void run() {
System.out.println("In threadDemo run method");
lg.show(10);
}
}).start();
new Thread(new Runnable() {
public void run() {
System.out.println("In thread2 run method");
lg.display(5);
}
}).start();
System.out.println("Hi, in main");
}
}
class LogicClass {
boolean value;
public LogicClass(boolean value) {
this.value = value;
}
synchronized void show(int a) {
if (value) {
for (; a != 0; a--)
System.out.println("This Output should come first");
value = false;
notifyAll();
}
}
synchronized void display(int a) {
while (value) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (; a != 0; a--)
System.out.println("This should come later");
}
}