I am trying to stop a java thread if it is running for 6000 milliseconds.
Below code to kill the Thread R1 is failed to stop the thread. could you please correct code?
I have tried this code with while (!Thread.currentThread().isInterrupted()) to stop the thread.
import java.time.Duration;
import java.time.Instant;
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo(String name) {
threadName = name;
System.out.println("Creating " + threadName);
}
#Override
public void run() {
System.out.println("Running " + threadName);
try {
while (!Thread.currentThread().isInterrupted()) {
for (int i = 100; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(600);
}
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
Thread.currentThread().interrupt();
}
System.out.println("Thread " + threadName + " exiting.");
}
#Override
public void start() {
System.out.println("Starting " + threadName);
if (t == null) {
t = new Thread(this, threadName);
t.start();
}
}
}
public class Killthread {
public static void main(String args[]) throws InterruptedException {
Instant timeBefore = Instant.now();
ThreadDemo R1 = new ThreadDemo("Thread-1");
R1.start();
System.out.println("Afte thread start");
Thread.sleep(6001);
Instant timeAfter = Instant.now();
if (Duration.between(timeBefore, timeAfter).toMillis() > 6000) {
R1.interrupt();
// R1.stop();
System.out.println("Thread Interrupted due to Time limitation.");
}
}
}
You've got two problems in your code, firstly that you aren't sleeping your main thread long enough, and secondly that you're interrupting the wrong thread.
6001 ms isn't long enough to guarantee that your duration check will be true. When I run your code, the main method rarely enters the if block. If you change to it sleep for 6100 ms, it should consistently call the interrupt.
Your second problem is that you're interrupting R1, but you need to be interrupting t.
If you override interrupt() in ThreadDemo to pass the call down to t, then it will receive the interrupt and break its execution thread.
e.g.
#Override public void interrupt() {
t.interrupt();
}
The problem is, that you start a complete new, different and unnecessary thread in ThreadDemo::start.
#Override
public void start() {
System.out.println("Starting " + threadName);
if (t == null) {
t = new Thread(this, threadName);
t.start();
}
}
It should rather look like
#Override
public void start() {
System.out.println("Starting " + threadName);
super.start();
}
And get rid of that private Thread t; in ThreadDemo.
In please of calling t.start() from your overridden start method call super.start() which will call the start() of thread class, and is responsible to create new thread and register it with thread scheduler.
Related
I have 3 threads in my application, but I am allowed to run only 2 threads in parallel.
once 1 either of the tread will stop, 3rd thread will start.
I know Thread, runnable start(), run() etc in Java, But I dont know how to implement above situation. your little guidance will be very helpful
Try using semaphore;
public class Main {
private static final Semaphore SEMAPHORE = new Semaphore(2);
public static void main(String[] args) {
runThread(new Thread(() -> runInThread(1)));
runThread(new Thread(() -> runInThread(2)));
runThread(new Thread(() -> runInThread(3)));
}
public static void runThread(Thread thread) {
try {
SEMAPHORE.acquire();
thread.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void runInThread(int i) {
System.out.println("Thread " + i + " is running");
System.out.println("Thread " + i + " is waiting");
try {
Thread.sleep(i * 2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread " + i + " is finish");
SEMAPHORE.release();
}
}
I have been learning multithreading in Java since recently and I encountered an example in the book. It goes something like this.
class NewThread implements Runnable {
String name;
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start();
}
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while(suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
synchronized void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
class Te {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming thread One");
ob2.mysuspend();
System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
try {
System.out.println("Waiting for threads to finish.");
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
Now in this example as you can see, there is a resume and a suspend method which gets called a couple of times in the program's main method. But when I remove the synchronized block in the run method, it displays an error something like this.
Exception in thread "Two" java.lang.IllegalMonitorStateException
I acually wanted to know, why do we need the synchronized block for the while statement. Doesn't the while resume when the value of suspendFlag change?
Here's what could happen if there was no synchronization:
Thread A could check suspendFlag and find it to be true,
Thread B could set suspendFlag=false; and then call notify();
Thread A could then call wait() (because suspendFlag was true when it checked.), and now Thread A is hung, waiting for a notification that will never happen.
The synchronization prevents thread B from changing the suspendFlag in between the moment when thread A checked it, and the moment when thread A actually begins to wait for the notification.
So I have a Thread wherein ScheduledThreadPoolExecutor is created with periodic Task, so I want to stop my ScheduledThreadPoolExecutor from Task when condition occurs.
After that from Thread wherein ScheduledThreadPoolExecutor is existed to make a notify to another Thread. Perhaps I did something wrong, I cannot to send notify from InnerThread to parent Thread Buyer. After that from Buyer sending another notify to MasterContainer.
How can I do this?
import java.util.Date;
import java.util.concurrent.*;
public class Buyer implements Runnable {
private CommonObj cmnObj;
public Buyer(CommonObj msg) {
this.cmnObj = cmnObj;
}
#Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " is starting");
ScheduledThreadPoolExecutor sch = (ScheduledThreadPoolExecutor)
Executors.newScheduledThreadPool(1);
sch.setRemoveOnCancelPolicy(true);
FutureRunnable periodicTask = new FutureRunnable() {
#Override
public void run() {
try {
System.out.println("\t periodicTask Execution Time: "
+ ScheduledExample.fmt.format(new Date()));
try {
Thread.sleep(2 * 1000);
synchronized (this) {
System.out.println("\t periodicTask need to close: "
+ ScheduledExample.fmt.format(new Date()));
this.getFuture().cancel(true);
System.out.println("\t periodicTask cancelled: "
+ ScheduledExample.fmt.format(new Date()));
this.notify();
return;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\t periodicTask End Time: "
+ ScheduledExample.fmt.format(new Date()));
} catch (Exception e) {
}
}
};
Future<?> periodicFuture = sch.scheduleAtFixedRate(periodicTask, 3, 3, TimeUnit.SECONDS);
periodicTask.setFuture(periodicFuture);
synchronized (sch) {
try {
System.out.println(name + " is before wait");
sch.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + " is before notify");
this.notify();
}
System.out.println(name + " is ended");
}
}
abstract class FutureRunnable implements Runnable {
private Future<?> future;
public Future<?> getFuture() {
return future;
}
public void setFuture(Future<?> future) {
this.future = future;
}
}
In your code, your inner task syncronized on periodicTask and outer syncronized on sch, this does not work.
If you want to syncronize inner and outer thread, you should syncronize on the same object, as well as call wait and notify on the same object.
I'm learning Thread in java.
The following example shows how to suspend, resume and stop threads:
class MyNewThread implements Runnable {
Thread thrd;
boolean suspended;
boolean stopped;
MyNewThread(String name) {
thrd = new Thread(this, name);
suspended = false;
stopped = false;
thrd.start();
}
public void run() {
System.out.println(thrd.getName() + " starting.");
try {
for(int i = 0; i<1000; i++) {
System.out.print(i + " ");
if(i%10 == 0) {
System.out.println();
Thread.sleep(250);
}
synchronized(this) {
while(suspended) {
wait();
}
if(stopped) break;
}
}
} catch(InterruptedException ex) {
System.out.println(thrd.getName() + " interrupted.");
}
System.out.println(thrd.getName() + " exiting.");
}
synchronized void mystop() {
stopped = true;
suspended = false;
notify();
}
synchronized void mysuspend() {
suspended = true;
}
synchronized void myresume() {
suspended = false;
notify();
}
}
public class Suspend {
public static void main(String[] args) {
MyNewThread ob1 = new MyNewThread("My Thread");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending Thread.");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming Thread.");
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending Thread.");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming Thread.");
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Stopping Thread.");
ob1.mystop();
} catch(InterruptedException ex) {
System.out.println("Main Thread interrupted.");
}
try {
ob1.thrd.join();
} catch(InterruptedException ex) {
System.out.println("Main Thread interrupted.");
}
System.out.println("Main Thread exiting.");
}
}
But this block:
synchronized(this) {
while(suspended) {
wait();
}
if(stopped) break;
}
Why this block must be specified synchronized?
I know "synchronized" uses to control Threads's access to shared resource and how to use this key word, but in the example, there're only 2 threads: Main thread and ob1 thread. And Main thread does not enter that synchronized block or any synchronized method in MyThread class. I just cant figure out the reason.
I tried to remove the "synchronized" key word precedes the block. the program returned an error in thread "My Thread" while the main thread still finished it's execution.
To answer your direct question: you need to synchronize on this because you are calling wait() on this.
And in order for wait() to be called, the calling thread must own the monitor of the object wait() is called on.
So: you need that synchronized block (or method) to prevent an IllegalMonitorStateException for the following call to wait()!
I am developing my Spring boot application wich
gets two requests: /start and /stop.
I need to create one shared thread for all clients requests.
When the first request "/start" will be received from client, app will create one thread shared by local variable T1.
When the second request "/stop" will be received, app will set boolean variable of thread "stopped" to stop it and the thread should stop.
Is next code provides safe for this shared thread?
Should i use the local variable for thread object or need to
do it by another way?
package com.direct.webflow;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
#EnableAutoConfiguration
#Controller
public class WebApp {
ThreadDemo T1;
#RequestMapping("/start")
#ResponseBody
String start() {
synchronized(this){
if (T1 == null || T1.stopped) {
T1= new ThreadDemo( "Thread-1");
T1.start();
} else {
return "Already started!";
}
}
return "Thread started!";
}
#RequestMapping("/stop")
#ResponseBody
String end() {
if (T1 == null) {
System.out.println("Not started!");
return "Not started!";
} else if (!T1.stopped) {
T1.stopped=true;
System.out.println("Trying to stop!");
return "Stopped!";
} else {
return "Already stopped!";
}
}
public static void main(String[] args) throws Exception {
SpringApplication.run(WebApp.class, args);
}
}
package com.direct.webflow;
public class ThreadDemo extends Thread {
private Thread t;
private String threadName;
public volatile boolean stopped=false;
ThreadDemo(String name){
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
int i=0;
System.out.println("Running " + threadName );
while (!stopped) {
System.out.println("Thread: " +this.isInterrupted()+ threadName + ", " + i++);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Thread: STOP!");
break;
}
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start ()
{
stopped=false;
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}
This is very close. You need to add the synchronized(this) block in your controller end() method. Otherwise you may have a race condition if /stop and /start are being called simultaneously.
Since Spring controllers are singletons you are OK to use a member variable like you have done here.