Suppose a Java thread performs some I/O operation like reading a file with traditional blocking Java I/O.
The question is: What is the state of the thread while waiting?
I don't know if it is RUNNING (doing some active wait) or WAITING (maybe there is some kind of monitor that wakes up the thread when file data is ready).
How can I find it out?
Thanks.
A thread that is blocked in an I/O syscall should be in RUNNABLE state, according to my reading of the javadocs.
public static final Thread.State RUNNABLE
Thread state for a runnable thread. A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.
The other possible thread states are far more tightly specified, and the respective specifications make them clearly inapplicable.
I have confirmed this by testing (with OpenJDK Java 8 on Linux).
public class Test {
public static void main(String[] args) throws Exception {
Thread t = new Thread(new Runnable() {
public void run() {
try {
while (true) {
System.in.read(); // Block for input
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
t.start();
while (true) {
System.out.println("State: " + t.getState());
Thread.sleep(1000);
}
}
}
Now, hypothetically, if you designed your application so that one thread handed off I/O requests to second thread, then the first thread would be in WAITING (or possibly BLOCKED) state waiting for the I/O thread to deliver. However, normal Java I/O doesn't behave like that. The thread requesting I/O is the one that makes the syscall.
How can I find it out?
Write tests; see above.
Deep-dive the OpenJDK source code.
You can find the status of thread using Thread.getState(). It will return
java.lang.Thread.State
Related
I have spring scheduler method. And ExecutorService
#Scheduled(fixedRate = 5000)
public void startSchedule() throws IOException{
threadPool.submit(() -> {
if(.......)return;
try {
generate(reportTasck);
} catch (NurException | IOException e) {
e.printStackTrace();
}
});
}
Each 5 sec start my method and if a necessary condition - start new thread with my logic. How can I stop/pause particular thread?
I have button on veb page, and if I press it I need to stop my thread.
There is already quite some discussion on SO regarding the stopping of threads. For a variety of reasons you should not stop or kill a thread as e.g. noted here:
How do you kill a thread in Java?
In order to allow the thread to properly cleanup its resources it should be the thread's responsibility to terminate itself by e.g. periodically checking some condition using e.g. a shared variable or via the thread's interrupt flag. See this answer for more details:
How to stop a thread created by implementing runnable interface?
I have a function in Java. It normally returns a value after it completes its task. However, in some conditions it returns nothing. I create a runnable and run this function as a thread. However, because of its not returning a value, it does not finish although it does its task. The process stays alive because it waits a returning value. Is there a way to kill this thread after it is triggered or after a timeout? Stop() or Destroy() did not work. During debug, the thread is seen as alive and I want it to bi deleted/removed
Runnable runnable = new Runnable() {
#Override
public void run() {
int stat = RunMyFunction();
}
};
Thread thread = new Thread(runnable);
thread.start();
Java does not support killing a thread via any method on java.lang.Thread.
stop() and destroy() do look promising at first glance, but they have both been deprecated.
The documentation for destroy states:
This method was originally designed to destroy this thread without any cleanup. However, the method was never implemented. If if were to be implemented, it would be deadlock-prone
and stop:
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
Thus when the documentation says 'deprecated', what it really means is that they are broken and must never be used!?! The Java API designers put a lot of work into backwards compatibility of their APIs, where other languages would have removed these methods Sun decided to keep them as their internal guides (rightly or wrongly) do not permit the removal of a public api method.
So, the question remains. How is one to get a thread to exit from another thread? Sadly one must go out of ones way to poll an exit variable. This can be a custom variable, or it can be a standard flag within java.lang.Thread that is accessible via 'interrupted()'. The advantage of using interrupted() is that other Java APIs such as IO support this flag during otherwise blocking API calls and will exit throwing an InterruptedException. The detection of calling interrupt() is not immediate, as it sets a flag and relies on the Thread to poll the variable at some point in the future.
Oracle offers a tutorial on how to code using interrupt here.
The real problem you have is that RunMyFunction sometimes never terminates. As others have already stated, killing a thread is not intended in Java, so there is no good way to do it. Instead, you should reason about why you call a possibly non-terminating method. This looks like a code smell. Do the following:
If you are the author of RunMyFunction, make sure that it always terminates or it can be interrupted. You can do this by checking Thread.currentThread().isInterrupted() and throwing an InterruptedException when it is. E.g:
void run(){
while(...){ // this loop sometimes runs forever
if(Thread.currentThread().isInterrupted())
throw new InterruptedException(); // Now, we can "kill" this thread here
}
}
Using ExecuterService you can specify a timeout.
ExecutorService executor = Executors.newFixedThreadPool(1);
List<Callable<String>> tasks = new ArrayList<Callable<String>>();
tasks.add(new Callable<String>() {
#Override
public String call() throws Exception {
int stat = RunMyFunction();
return "Execution Finished";
}
});
new Thread(new Runnable() {
#Override
public void run() {
try {
executor.invokeAll(tasks, 10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
invokeAll(...) is a blocking call so i've added inside a new thread.
Solution 1: Timed run: If you want a method to return or throw an exception after a specified amount of time, use the following method to execute the method on a background thread while waiting for it to complete:
public static void timedRun(Runnable r, long timeout, TimeUnit unit)
throws InterruptedException, TimeoutException {
Future<?> task = executor.submit(r);
try {
task.get(timeout, unit);
} catch (ExecutionException e) {
throw launderThrowable(e.getCause());
} finally {
task.cancel(true);
}
}
private static RuntimeException launderThrowable(Throwable t) {
if (t instanceof RuntimeException) return (RuntimeException)t;
else if (t instanceof Error) throw (Error)t;
else throw new IllegalStateException("Not unchecked", t);
}
(Source: Goetz, Brian, Bloch, Joshua, Bowbeer, Joseph, Lea, Doug, Holmes, David and Peierls, Tim. Java Concurrency in Practice. : Addison-Wesley Longman, Amsterdam, 2006. Listing 5.13 and 7.10)
For executor, you can either create a new one using Executor.newSingleThreadExecutor(), or reuse an existing one.
But be warned: Although this method is guaranteed to return or throw an exception after the specified timeout, it cannot guarantee that the runnable will really stop! It interrupts the executing thread, but if the runnable does not react to thread interruption (e.g. by internally checking Thread.interrupted()), it may continue to run in the background - possibly forever - occupying a thread! But at least it does not block.
Solution 2: Timed run with custom threads: If there is any possibility beside thread interruption to cancel your method call, you can still use the approach above, but then you have to use an Executor with custom ThreadFactory that creates a special Thread instance with overridden interrupt method:
Executor executor = Executor.newSingleThreadExecutor(r -> new WsdlThread(r));
public class WsdlThread extends Thread {
public WsdlThread(Runnable r) { super(r); }
public void interrupt() {
try {
// TODO: do something that will interrupt the wsdl call
// e.g. close connection to server, etc.
// example: ((WsdlRunnable)r).getWsdlConnection().close();
} finally {
super.interrupt();
}
}
}
If this isn't possible too, and Thread.stop() doesn't work either, this last solution might work:
Solution 3: Start non-cancellable call in another JVM:
Use Runtime.exec to start another JVM and execute the method call there (See Executing a Java application in a separate process for more info on how to do this). Runtime.exec will return a Process object, which represents the running process.
You can kill it by calling destroy() or destroyForcibly().
We use Hazelcast 2.6.2 in a legacy Java clustered application. When the application is stopped the JVM does not terminate any more. It seems that it is caused by Hazelcast threads not being flagged daemon. I did not find a way way through the Hazelcast API to flag them daemon.
Are there recommended solutions to prevent Hazelcast from preventing the JVM to terminate?
Regards
Looking at the Hazelcast Javadocs, I see that there is a shutdownAll(); method. To quote the javadocs:
Shuts down all running Hazelcast Instances on this JVM, including the default one if it is running. It doesn't shutdown all members of the cluster but just the ones running on this JVM.
If you aren't shutting it down I suspect there are non-daemon threads there that aren't being terminated that will keep the JVM from closing.
In Tomcat, I added a lifecycle listener via server.xml.
<Listener className="com.mycompany.StartupHandler" DEBUG="false"/>
My StartupHandler.class went in a jar in $TOMCAT_HOME/lib/, and it contains this snippet to trigger Hazelcast shutdown when Tomcat shutdown is detected:
public void lifecycleEvent(LifecycleEvent lifecycleEvent) {
String eventType = lifecycleEvent.getType();
if (eventType.equals(Lifecycle.BEFORE_STOP_EVENT)) {
com.hazelcast.core.Hazelcast.shutdownAll();
}
}
Other web servers should have similar shutdown hooks where you can invoke Hazelcast.shutdownAll() automatically.
See https://github.com/hazelcast/hazelcast/issues/718 for my original Hazelcast thread on the same topic. Thanks for the hint here to call Hazelcast.shutdownAll(). That idea combined with my Tomcat shutdown hook should be sufficient to resolve this problem for me, and hopefully you find it useful too.
Here is a Tomcat independent way to detect JVM shutdown. It uses a non-daemon thread to poll a daemon thread to detect when the JVM is shutting down (the JVM shuts down daemon threads automatically). Poll the static IS_SHUTDOWN flag in your code, or inline the call to Hazelcast.shutdownAll() here. Be careful of a race condition, because if you try to shutdown Hazelcast before it starts then it throws an exception in your log. The exception does not break anything, but it looks ugly.
/**
* Non-Daemon thread monitors a sacrificial, low-priority, daemon thread
* to detect when JVM is shutting down, so shutdown hooks can be invoked.
* #author justin.cranford
*/
public class ThreadUtil {
public static boolean IS_SHUTDOWN = false; // threads can poll this flag, or inline below where flag is set
private static final Thread DAEMON_THREAD = new Thread() {
public void run() {
while (true) {
try {
Thread.sleep(Long.MAX_VALUE); // sleep forever
} catch(Exception e) {}
}
}
};
private static final Thread NONDAEMON_THREAD = new Thread() {
public void run() {
while (true) {
if (!DAEMON_THREAD.isAlive()) { // poll forever, until daemon thread dies
ThreadUtil.IS_SHUTDOWN = true;
return;
}
try {
Thread.sleep(1000); // poll every 1000msec = 1sec
} catch(Exception e) {}
}
}
};
static {
DAEMON_THREAD.setName("ShutdownMonitorNonDaemonThread");
DAEMON_THREAD.setPriority(Thread.MIN_PRIORITY);
DAEMON_THREAD.setDaemon(true);
DAEMON_THREAD.start();
try {
Thread.sleep(3000); // wait 3000msec = 3sec before monitoring
} catch(Exception e) {}
NONDAEMON_THREAD.setName("ShutdownMonitorDaemonThread");
NONDAEMON_THREAD.setPriority(Thread.MIN_PRIORITY);
NONDAEMON_THREAD.setDaemon(false);
NONDAEMON_THREAD.start();
}
}
As everyone said, hazelcastInstance.shutdownAll() is the solution.
But, I would to get a new feature in Hazelcast - provide a demon client as well. There are many use cases where cache instance needs to be shutdown as soon as application ends.
I'm getting some exception and I need to know when the program closes itself because I need to close the socket.
I have the default public static main method where I'm keep repeating an action and a Thread class.
private static Thread thread;
public static boolean isRunning = true;
public static void main(String[] args){
thread = new Thread(new ThreadListenServer());
thread.start();
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run(){
// some action
}
}
timer.scheduleAtFixedRate(task, 0, 10000);
isRunning = false;
}
And the thread class which is running in background:
public class ThreadListenServer implements Runnable{
private DatagramSocket socket;
public ThreadListenServer() throws SocketException{
socket = new DatagramSocket(6655);
}
#Override
public void run() {
while(MainProgram.isRunning){
// some action
}
socket.close();
}
}
I don't know why, but isRunning it's becoming false, but it shouldn't. How am I supposed to close the socket if the main program was closed? (It's causing because the Thread still running in the background even if the program was closed).
I was thinking about to create the socket in the main class then I pass the socket object as a parameter to the ThreadClass and if the program is closed, than I should close the socket as well.
Use:
thread.setDaemon(true);
This will shut the thread. It tells the JVM it is a background thread , so it will shut down on exit.
Ill take the assumption you have a JFrame of some sort running as the class MainProgram. You have 2 options
1: set your Jframe to close all threads when it is closed.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
2: add a window listener and manually close your thread (maybe you have to send some information across the socket before you close it)
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
// send your socket its close message and shut everything down
System.exit(0);
}
});
To stop all Threads when your program exits cleanly, you'll need to define a termination policy for each Thread that gets started. This is normally done using Interrupts and ExecutorService.shutdownNow() method sends an interrupt to each running thread.
A clean termination policy consists to two parts:
Sending stop signal to thread – aka interrupting it
Designing threads to act on interruption
A thread in Java could be interrupted by calling Thread.interrupt() method. Threads can check for interruption by calling Thread.isInterrupted() method. A good thread must check for interruption at regular intervals, e.g. as a loop condition and checking blocking functions for InterruptedExceptions.
It is important to note that Sockets in Java are oblivious to interruption. For example, if a Thread is blocked on Socket.accept(), it will not throw InterruptedException when the Thread is interrupted. In this case, you need to define a public method which closes the underlying socket by calling Socket.close() forcing the blocking function to throw an Exception (I guess SocketException).
A few things come to mind.
It would appear you are performing a blocking I/O operation using sockets. You may need to interrupt either the running thread and/or the socket to get it to stop blocking
You should set the thread as daemon thread before it is started, using setDaemon(true). This will allow the JVM to terminate the thread automatically...
isRunning should be marked volatile or you should use AtomicBoolean instead
How to kill the thread?
.....
How to restart them again in multi threading?
Since your post is tagged "Java," I have a good idea of what you are saying. Let's say you start a thread by doing:
Thread foo = new Thread(someRunnable);
foo.start();
Now that destroy and friends are deprecated, you need a way to kill the thread. Luckily for you, there has always been the concept of "interrupts." Simply change your runnable so that, on interrupt, it exits. Then call the thread's interrupt method.
foo.interrupt();
If you wrote your Runnable to handle this correctly, it will stop whatever it is doing and terminate.
Thread.stop() kills a thread, but you definitely don't want to do this (see the API documentation for an explanation why). Thread.interrupt() sends an asynchronous notification to a thread, so that it can shut itself gracefully.
For a comprehensive text on Java multithreading, I recommend B. Goetz, Java Concurrency in Practice, Addison-Wesley Professional.
The preferred way for a Thread to die is for the execution of the run method to go to completion:
Thread t = new Thread(new Runnable() {
public void run() {
// Do something...
// Thread will end gracefully here.
}
}
Once a thread gracefully dies in the example above, the Thread cannot be restarted. (Trying to call Thread.start on a thread that has already been started will cause an IllegalThreadStateException.)
In that case, one can make another instance of the thread and call start on that.
Probably a good place to get more information on threading would be Lesson: Concurrency from The Java Tutorials.
i wrap my worker threads up in their own class and use a terminated property to kill the thread proc loop.
sorry i dont have a java version to hand right now but you should get the idea from this
http://pastie.org/880516
using System.Threading;
namespace LoaderDemo
{
class ParserThread
{
private bool m_Terminated;
private AutoResetEvent m_Signal;
private string m_FilePath;
...
public ParserThread(AutoResetEvent signal, string filePath)
{
m_Signal = signal;
m_FilePath = filePath;
Thread thrd = new Thread(this.ThreadProc);
thrd.Start();
}
public bool Terminated {
set { m_Terminated = value; }
}
private Guid Parse(ref string s)
{
//parse the string s and return a populated Guid object
Guid g = new Guid();
// do stuff...
return g;
}
private void ThreadProc()
{
TextReader tr = null;
string line = null;
int lines = 0;
try
{
tr = new StreamReader(m_FilePath);
while ((line = tr.ReadLine()) != null)
{
if (m_Terminated) break;
Guid g = Parse(ref line);
m_GuidList.Add(g);
lines++;
}
m_Signal.Set(); //signal done
}
finally
{
tr.Close();
}
}
}
}
The best way to kill a thread is to set up a flag for the thread to watch. Program the thread to exit when it sees the flag is set to true. There's no way to restart a killed thread.
If you want to start, stop, restart threads at will, maybe using the Java 5 concurrency package would be a good idea. You can have an Executor that will do a bit of work, and when you need that bit of work to be done again, you can just re-schedule it to be done in the executor.
Regarding your first query on killing thread:
You can find more details about topic in below SE questions:
How to properly stop the Thread in Java?
How can I kill a thread? without using stop();
How to start/stop/restart a thread in Java?
Regarding your second query of re-starting thread, it's not possible in java.
You can find below details in documentation page
public void start()
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.
Instead of plain Threads, you can use advanced concurrent API for thread life cycle management. Have a look at this post for ExecutorService details :
How to properly use Java Executor?