I am writing a java program which tracks as threads are created in a program and is then supposed to perform some work as each Thread terminates.
I dont see any 'thread termination hooks' out there in the javadoc.
Currently the only way I can think of to achieve my requirement is to hold on to the thread objects and query its 'state' at repeated intervals.
Is there any better way to do this?
Edit:
I cannot wrap the runnable or modify the runnable in any way.
My code uses runtime instrumentation and just detects that a thread is created and gets a reference to the Thread object.
The runnable is already running at this point.
You can use the join() method.
EDIT
If your main thread must not be blocked until threads are not terminated, you can create a sub main thread which will call the threads, then wait for them with join() method.
I see four possible methods.
Use your own Thread subclass with an
overridden run() method. Add a
finally block for thread
termination.
Use a Runnable with
similar decoration, perhaps as a
wrapper around the supplied
Runnable. A variant of this is to
subclass Thread in order to apply
this wrapper at construction time.
Create a 2nd thread to join() on the
real thread and thus detect its
termination.
Use instrumentation to rewrite the Thread.run() method as above.
Just poking around in the (sun 1.5) source code for java.lang.Thread and sun.misc.VM, there is a field in thread called threadStatus. It is a private int and its values map to the enum java.lang.Thread.State. I have not verified this, nor determined how quickly it occurs if it does, but when a thread eventually terminates, this value will be set to java.lang.Thread.State.TERMINATED.
With this relatively simple condition to detect, I think it would be fairly straightforward to inject a field interceptor on threadStatus to fire an event when the field is set to a specific target value.
You could write a decorator for Runnable which calls a termination hook and wrap your thread code in it when you create the threads.
If you added a try/finally block to each run method, the code inside would be executed when each thread completed. Let the thread be responsible for its own clean-up.
AspectJ could help you do this if you needed to inject code into third-party compiled code, but apparently it doesn't work on standard Java class libraries.
Looks like there's a whitepaper on doing this here, but there's no telling if it's practical. I think you have to pay for it.
http://portal.acm.org/citation.cfm?doid=1411732.1411754
You could download OpenJDK, put the hook in yourself, compile a custom JRE and ship that with your application :)
As you say, there are no thread termination hooks. You have to code them yourself; call some method on a controller at the end of the run() method of your Runnables (AFAIK subclassing Thread is considered bad practice, you should implement Runnable and create a Thread with that Runnable as its target).
You can also implement an UncaughtExceptionHandler to know if a thread terminated abnormally due to an exception, in which case your controller's method won't be called.
If you run on java 1.5 you can probably do it using java.lang.instrument and the -javaagent option to the jvm.
Redefine the run method on the thread object which should call your code. You already seem to use instrumentation so it should be available. as it modifies runtime bytecode you should be fine
That said, it is hard to provide a more specific and detailed answer your question lacks at least the jvm version and the main frameworks in use (think spring-aop, jboss-aop, jvm version etc)
Related
I am calling a method using reflection in Java using the method.invoke function. Does that method.invoke create a new thread or it will run with the current thread?
No, it does not create a new thread.
The JavaDocs don't mention anything about multithreading or being asynchronous, and this is typically a very strong indication that it will be executed in the current thread.
Constructs that may use other threads are typically quite explicit about not making any guarantees as to which thread will execute the code - see the documentation for Executors or Stream
As far as I understand Guava's MoreExecutors.directExecutor() creates an Executor which will executes the runnable before the execute method call could return.
What are the usecases that need direct executor ? Can't the caller directly call runnable.run() directly instead of the extra level of indirection by creating an executor and submitting the runnable to this executor ? May be I am missing the real purpose of it's existence. I wanted to understand in what case is this useful.
There are few places which require both Runnable and Executor.
One of then is for example ListenableFuture and its addListener method. The only way how to execute listener immediately within the same thread is to provide direct executor.
MoreExecutors.directExecutor() is useful when you call an API that requires you to specify an executor to execute the task (e.g. Futures.transform(), listenableFuture.addListener(), etc).
Note that when you use directExecutor() with these APIs, the runnable may be run on one of these two threads:
The thread that completes the previous future
The thread that calls transform()/addListener()
This uncertainty could cause unexpected issues. So be careful when you use directExecutor().
I am trying to stop a current thread, change the run() method, and then restart that thread. I've looked around, and most of the methods are deprecated. However, interrupt() is not. I'm not sure if that's all you need to do.
interrupt();
start();
Would that work for what I needed it to do? It says that you should never start a thread more than once, and I don't know if it means
start();
start();
Rather than what I wanted to do.
Any help is appreciated.
Thanks
No, you can't do that. Fron the java online docs:
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
Don't restart a thread. You ALWAYS can rewrite your buisness logic to do this some other way. Consider using SingleThreadExecutor
In this case, you should create a Runnable object and pass it to a thread. Then you're creating different threads, but re-using the 'work' object.
Once you've started a thread, you can only interrupt it. Once you've done that, you can't start it again. See here for more details.
I'm not quite sure what you want to do, but it sounds like you have different Runnables that you want to run in sequence. In this case use a SingleThreadExecutor and submit your Runnables. It will run these in order, and so interrupting the first (successfully) will invoke the second.
I'm still not sure this is a good idea (it just doesn't sound right) and perhaps posting a more detailed problem description will give people a better idea of what you're really trying to do.
You should look into the basics of threading more. A thread can only run once. If you want to have the thread run different code, you need to create a new thread.
The interrupt() method will not stop a thread immediately (there is no supported) way to do that, it will stop only at certain points by throwing an InterruptedException().
I think you're approaching your problem in the wrong way. You cannot 'change the run() method of a Thread'. However what you probably want is to stop the previous thread and create a new one with a different run() method.
One thing to keep in mind however, is that Threads are designed to be as autonomous as possible and they don't like interference from other threads, which is why suspend() and resume() are deprecated. They create all sorts of bad behaviour depending on the circumstances and also prone to deadlocks.
You have 2 perfectly safe alternatives however:
Use wait() and notify() on a specific shared object.
Use sleep() and interrupt()
You need to decide within the run() method where it is safe to 'stop' the thread, and at that point put a wait() or sleep(). Your thread will only stop at that point.
The other thread can then do a notify() or sleep() so that the running thread is notified or interrupted. In case of interrupt() you will get an InterruptedException which you can use to terminate what you were doing in that thread.
After interrupting the old thread you can start a new thread initialised with a new Runnable implementation which has the different run() method.
Calling interrupt() will set the thread's interrupt status potentially interrupting blocking methods. This is part of a cooperative cancellation mechanism. You can't use it to force the thread to stop running.
Stopping threads has been deprecated for a reason: it is inherently dangerous as it may leave the state variables which it is manipulating in an inconsistent state.
You should not do this. Make your code from the run() method into a Runnable and submit it for execution to an Executor. This will return you a Future which you can use to retrieve its results as well as to cancel it.
If you want to reuse the same thread for other computations, use a thread pool, see for example Executors.newFixedThreadPool() and other factory methods in Executors.
What is the essence of allowing the user to create thread by extending the Thread class when we can achieve the same functionality by implementing Runnable and pass it to the Thread constructor.
achieve the same functionality by
implementing Runnable and pass it to
the Thread constructor
The use of extending Thread is not limited to Runnable. For example you can change the behavior of some methods or add your own thread local information (always accessible with Thread.currentThread()).
From a historical perspective, you need to understand that the Thread API was designed in Java 1.0, before Java supported anonymous inner classes. And a lot of the early example code shows subclassing of Thread. It wasn't until later that:
they added support for anonymous inner classes (Java 1.1)
they figured out it was better to use inner classes (etc) to provide Runnable instances
they implemented standard classes for task execution, thread pools and so on (Java 5.0).
It is all very well saying "the Thread class in .Net is marked final", but you have to realize that C# / .Net came along a number of years later ... and was able to learn from the design of Java. Java was / is stuck with the historical baggage of a number of less-than-perfect design decisions ... because of an overriding imperative to NOT break old code.
Thread is unusual in that it can take a reference to the Runnable to run, but it itself is also Runnable. By default, the Thread will use itself as the Runnable instance to run, though of course you can point it someplace else.
I think that that's no good reason to either mark Thread final and require an external Runnable or to make Thread extendible and have it be its own Runnable. Both approaches are perfectly fine and neither one seems like a much better choice than the other.
If I had to guess, the reason for making Thread subclassable is that it allows you to write code like this:
Thread t = new Thread() {
public void run() {
/* ... your code here ... */
}
};
Which is marginally cleaner than creating a subclass of Runnable and then wrapping it in a thread. Similarly, you can subclass off of Thread to get a Runnable that clearly indicates that it's supposed to be used as a thread. Of course, this is mostly a question of aesthetics, and had the Java designers gone the other way with this I think it would have been a perfectly fine decision.
If I acan add something, by extending Thread you can have extended functionality of a thread (which is doesn't exist in Runnable as it only contains the run() method) like allowing your thread to act as a daemon thread (just like the Garbage Collector Daemon Thread). Other threads exists like the single non-daemon thread which calls the main method of a class (when the JVM starts up).
The Runnable interface allows your class to become active as thread (by implementing a run() method).
The thread class describes how the thread runs, the Runnable describes what is run. If you want to modify what is run, you should implement Runnable. If you want to modify how the thread is run you derive from Thread. In the case where you want to modify how a thread is run, you may derive from Thread and implement a separate Runnable object.
The only good thing I can think of is: if you extend the Thread class, It lets your run() method to be marked as protected. One disadvantage of implementing Runnable is that your run method MUST be marked as public.
i am facing a problem regarding the thread. I am having a class which implements runnable, and i can use thread.start() method on that class.
My question is i have one more class java.util.concurrent.ExecutorService in which i can call executor.submit(thread)..
can anyone please tell me what is the difference between thread.start() and executor.submit(thread)...
The executor.submit method takes a Runnable, not a Thread. The point of executorServices is that they take control over creating and pooling threads so the code calling them doesn't have to.
You should not submit a thread to an executor. First it is simply a waste because the only method that will be called on it is run(), and you just need a Runnable and don't need a Thread for that.
Secondary, while this issue is solved in the latest JDK, it used to be the case that a memory leak problem occurs if you create a lot of Thread objects and don't call .start() on them. Basically creating a Thread objects allocates some memory that can only be reclaimed after .start() was called. Therefore, doing executor.submit(thread) is potentially hazardous in earlier JDKs (I think it was only solved in JDK6 or so).
Coming back to your question, executor.submit(thread) is not valid.. It is simply wrong, because an executor uses its own thread to execute the runnable. That's after all the whole point of using a executor. You want to separate task (invocation) and execution. Only if you want to supply the executor (thread), you should be using Thread, but it is rare that you need to do so. Generally it is advisable to implement a Runnable and use executors to execute it, rather than dealing with Thread yourself.