According to the information I've got so far, I've understood that Thread.sleep() pauses the thread where the method is called. For example, if I call it within the main method it pauses the execution of main. if I call it inside the run of a certain thread, it would only pause that thread.
I need an expertise to confirm my understanding as I feel lost among the too much information on web.
I've been practicing to apply this, throw the following:
a Thread class, Player1:
public class Player1 extends Thread{
public void run()
{
try {
System.out.println("I'm going to sleep");
Thread.sleep(2000);
System.out.println("I'm awake");
} catch (InterruptedException ex) {
}
}
}
a Thread class, Client:
public class Clients extends Thread {
public void run()
{
printer2(10);
}
public synchronized static void printer2(int val)
{
System.out.println(val);
System.out.println(val);
System.out.println(val);
System.out.println(val);
System.out.println(val);
System.out.println(val);
}
}
they're called inside main method:
public static void main(String[] args) throws InterruptedException {
Clients c1 = new Clients(10);
Player1 p = new Player1();
p.start();
c1.start();
}
What happens (according to my understanding): the sleep is applied only to the execution of the player1 thread not to the main thread or the client thread.
Similarly, if I add a sleep method in the run of the Clients thread, it would sleep independently of the other Thread. for instance: this sleeps for its own 1 second and this sleeps for its 1 second as well (even if those 2 1 seconds overlap)
Correct me if I'm wrong please
Thanks in advance!
Related
These are the 3 classes I have:
public class ChildThread extends Thread {
#Override
public void run() {
while (true) {
System.out.println("Child thread is running.");
if (Thread.currentThread().isInterrupted()) {
System.out.println("Child thread is interrupted.");
return;
}
}
}
}
public class MainThread extends Thread{
public Thread childThread = new ChildThread();
#Override
public void run() {
childThread.start();
}
}
public class App {
public static void main(String[] args) {
MainThread mainThread = new MainThread();
mainThread.start();
mainThread.childThread.interrupt();
}
}
When I run this, the child thread doesn't seem to be ever interrupted. It keeps printing: "Child thread is running."
However, if I put a debug breakpoint at mainThread.childThread.interrupt();, child thread will get interrupted.
And also, if I change App class like the following:
public class App {
public static void main(String[] args) throws Exception{
ChildThread childThread = new ChildThread();
childThread.start();
Thread.sleep(3000);
childThread.interrupt();
}
}
it works again. Child thread gets interrupted and stopped printing after 3 seconds.
It seems that the behaviors are different interrupting from a thread that directly started a child thread, and from a thread that didn't directly start a child thread. And it's also different depending on whether there's a breakpoint or not. It's so weird to me. How could this work in a complex system? I don't think a complex system can guarantee all interruption signals are from the original starters of threads.
Could anyone help explain this? I can't find anywhere that seem to have an answer.
You need the Thread.sleep before interrupting otherwise, you are interrupting before the child thread even before it has gotten a chance to start running. As per the API specs "Interrupting a thread that is not alive need not have any effect.". So, in affect, the interrupt statement is being ignored as at the time the thread is not active. Without the sleep, the thread become active AFTER the interrupt - hence is never interrupted.
public class App {
public static void main(String[] args) throws InterruptedException {
MainThread mainThread = new MainThread();
mainThread.start();
Thread.sleep(1); // <== This line is needed as otherwise, the next line will
// interrupt the thread, even before it has started running!
mainThread.childThread.interrupt();
}
}
i am new to multithreading and trying to clear my basics.
public class SleepExample extends Thread {
private int counter = 0;
#Override
public void run() {
try {
counter++;
System.out.println("Value of counter "+counter);
System.out.println("Thread going in sleep "+Thread.currentThread().getName());
Thread.currentThread().run();
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
System.out.println("Thread out of sleep "+Thread.currentThread().getName());
}
public static void main(String[] args) {
new SleepExample().start();
new SleepExample().start();
Test test = new Test();
Thread t = new Thread(test);
t.start();
}
}
//another class implementing runnable
public class Test implements Runnable {
#Override
public void run() {
System.out.println("In Test runnable method");
}
}
When i run this code, my run method of SleepExample recursively call itself after below line
Thread.currentThread().run();
for thread belonging to SleepExample (Thread -0, Thread -1) and
it goes to run method of Test class for thread t.
I am unable to understand the usage of Thread.currentThread().run();
P.S. - I read its java doc and so i have implemented a runnable
I am unable to understand the usage of Thread.currentThread().run();
You are not supposed to call it directly. From Thread.start() You are supposed to use start() to call run() and that is it.
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
You are already running in the run() so you should only call this if you can say why you are doing it, even then it will look like a bug or be plain confusing and I would suggest you use a loop instead.
When i run this code, my run method of SleepExample recursively call itself after below line
You have a method calling itself, so you should expect that to happen. There is nothing special to Thread in this regard. It is like any other recursive call in a method.
In my run() method of my Thread class, I am calling a never ending function.
I need the thread to run only for a specific duration.
Am not able to control the thread once its started, Is their any way to destroy it?
I have tried yield(), sleep(), etc...
PS - I cannot change the never ending function
From oracle Java Docs:
public void run(){
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
if (Thread.interrupted()) {
// We've been interrupted: no more crunching.
return;
}
}
}
Your thread should check interrupted condition after each loop to see if it was interrupted. If you are calling a method that just does while(true){} then I am afraid there is no way interrupting it and stop() MUST never be called on a thread.
It is the programmers responsibility to make a long running method responsive to interrupts.
http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html answers all your questions.. particularly section What should I use instead of Thread.stop?
Hope it helps
This could be too much, but this is how I would solve it, if you do not want to mess with Interrupt.
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
ThreadTest test = new ThreadTest();
test.go();
}
void go() throws InterruptedException{
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(new LongRunnable());
if(!service.awaitTermination(1000, TimeUnit.MILLISECONDS)){
System.out.println("Not finished within interval");
service.shutdownNow();
}
}
}
class LongRunnable implements Runnable {
public void run(){
try{
//Simultate some work
Thread.sleep(2000);
} catch(Exception e){
e.printStackTrace();
}
}
}
Basically you are wrapping your runnable in a ExecutorServie and if it's not finished within the interval, you basically kill it - send the interruption to it.
I have been looking for ways to kill a thread and it appears this is the most popular approach
public class UsingFlagToShutdownThread extends Thread {
private boolean running = true;
public void run() {
while (running) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {}
}
System.out.println("Shutting down thread");
}
public void shutdown() {
running = false;
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.shutdown();
}
}
However, if in the while loop we spawn another another object which gets populated with data (say a gui that is running and updating) then how do we call back - especially considering this method might have been called several times so we have many threads with while (running) then changing the flag for one would change it for everyone?
thanks
One approach with these problems is to have a Monitor class which handles all the threads. It can start all necessary threads (possibly at different times/when necessary) and once you want to shutdown you can call a shutdown method there which interrupt all (or some) of the threads.
Also, actually calling a Threads interrupt() method is generally a nicer approach as then it will get out of blocking actions that throw InterruptedException (wait/sleep for example). Then it will set a flag that is already there in Threads (which can be checked with isInterrupted() or checked and cleared with interrupted(). For example the following code can replace your current code:
public class UsingFlagToShutdownThread extends Thread {
public void run() {
while (!isInterrupted()) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) { interrupt(); }
}
System.out.println("Shutting down thread");
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.interrupt();
}
}
i added a utlility class which essentially had a static map and methods.
the map was of type Long id, Thread thread. I added two methods one to add to the map and one to stop the thread via the use of interrupt. This method took the id as a parameter.
I also changed my loop logic from while true, too while ! isInterrupted. Is this approach ok or is this bad programming style/convention
thanks
This is good example of stopping thread.
How to stop a java thread gracefully?
But when I try to check this example I received infinite loop.
This is my code:
public class Num {
public void crash(ManualStopping t1) {
t1.stopMe();
}
public static void main(String[] args) {
Num num = new Num();
ManualStopping t1 = new ManualStopping();
t1.run();
System.out.println("Main thread");
num.crash(t1);
}
}
class ManualStopping extends Thread {
volatile boolean finished = false;
public void stopMe() {
finished = true;
}
public void run() {
while (!finished) {
System.out.println("I'm alive");
}
}
}
I think you need to start your thread - not run it. By calling run, you are just making a normal method call, not running a separate thread.
Nothing in your code calls the stopMe method on ManualStopping. isInterrupted() is a test that doesn't change the state of the thread. And as #DaveHowes points out, you don't even start a separate thread.
t1.run(); Change it to t1.start().
Whats happening is that the thread you intend to spawn is not actually running as a separate thread. Instead the loop
while(!finished){ System.out.println("I'm alive"); }
is running on the main thread and your code num.crash(t1); never actually gets invoked. This is causing the infinite loop.