Use of Thread.currentThread().join() in Java - java

The following code is taken from an example in the Jersey project. See here.
public class App {
private static final URI BASE_URI = URI.create("http://localhost:8080/base/");
public static final String ROOT_PATH = "helloworld";
public static void main(String[] args) {
try {
System.out.println("\"Hello World\" Jersey Example App");
final ResourceConfig resourceConfig = new ResourceConfig(HelloWorldResource.class);
final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, resourceConfig, false);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
server.shutdownNow();
}
}));
server.start();
System.out.println(String.format("Application started.\nTry out %s%s\nStop the application using CTRL+C",
BASE_URI, ROOT_PATH));
//////////////////////////////
Thread.currentThread().join();
//////////////////////////////
} catch (IOException | InterruptedException ex) {
//
}
}
}
I understand what is going on apart from the use of Thread.currentThread().join();.
I'm a Java newbie and my understanding is that this will block the execution of the current thread (in this case, the main thread), and effectively deadlock it. i.e. it will cause the current (main) thread to block until the current (main) thread finishes, which will never happen.
Is this correct? If so, why is it there?

Thread.currentThread().join() blocks the current thread forever. In your example, that prevents the main from exiting, unless the program is killed, e.g. with CTRL+C on Windows.
Without that line, the main method would exit right after the server is started.
An alternative would have been to use Thread.sleep(Long.MAX_VALUE);.

It's a common misunderstanding that if the main thread exits, the program will exit.
This is only true if there is no non-daemon thread running. This may be true here, but usually it is better IMHO to make the background threads this main is "waiting" for non-dameon and let the main thread exit when it doesn't have anything to do. I have see developers put Thread.sleep() wrapped in an infinite loop. etc.

It's an example. It's just not a very good one.
They're trying to show you how to make a thread that runs forever.
Thread.currentThread().join(); is a statement that takes forever to complete. You're supposed to replace it with your own code that runs forever and, presumeably does something useful.

Related

Why is Thread.sleep halting the main thread? [duplicate]

I created my own thread class implementing the Runnable interface. But every time I start running my own thread class as a new thread, the main class thread does not terminate anymore by itself. Is this just an issue within Eclipse or would I also have problem running this on a Server? Do I have to change something calling the thread so that the main method can terminate properly?
Here's my basic self-made thread:
public class OwnThread implements Runnable {
#Override
public void run() {
//do something
}
}
Here's the main class that won't terminate anymore:
public static void main(String[] args) {
Thread thread = new Thread(new OwnThread());
thread.start();
}
When I debug it, the last called method is the exit()-method of the Thread-class. After going through these lines of code, the process goes on forever:
/**
* This method is called by the system to give a Thread
* a chance to clean up before it actually exits.
*/
private void exit() {
if (group != null) {
group.threadTerminated(this);
group = null;
}
/* Aggressively null out all reference fields: see bug 4006245 */
target = null;
/* Speed the release of some of these resources */
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
Here's a screenshot of the thread that is running forever. The TestInterface class is where the main-method is located:
But every time I start running my own thread class as a new thread, the main class thread does not terminate anymore by itself.
This is somewhat wrong. Your program does not terminate because there exists at least one non-daemon thread that still is running. The rule is: A Java program is terminated if all non-daemon threads are terminated.
I modified your program to make this behavior clear:
public class OwnThread implements Runnable {
#Override
public void run() {
runForever();
}
public static void main(String[] args) {
Thread thread = new Thread(new OwnThread());
thread.start();
runForever();
}
private static void runForever() {
while (true) {}
}
}
Running that will create two threads that will run forever. One is the main thread which is started by running the program, and the other is the thread started inside the main method:
Modifying the above code by removing the call to runForever in the main method ...
public static void main(String[] args) {
Thread thread = new Thread(new OwnThread());
thread.start();
}
... will result in a different thread picture:
Here the main thread is gone because it is terminated. But the other started thread is still running.
Side note: Suddenly another thread appears - DestroyJavaVM. Have a look at the post DestroyJavaVM thread ALWAYS running for more information.
The issue is indeed not caused by the multithreading logic itself, it is caused by Eclipse and the respective JVM. Running the exact same code in Netbeans or on an Tomcat 8 Server did not lead to any problems. A reinstallation of Eclipse did not solve the malfunction within the Eclipse framework, but having the certainty that the issue does not cause any trouble on a server is sufficient for me to close the case.
Thanks to Seelenvirtuose for the hints and his effort.

Force method to finish before continuing

I'm working on some sensitive LWJGL code and need to make sure that I create my display, and therefore GL context before executing any other code.
To give a clear example of my current predicament, take the following:
public static void main(String[] args) {
GLDisplay display = new GLDisplay();
display.start();
GLShader shader = new StaticShader();
}
The beginning of my GL creation happens in display.start(), where a separate thread is created, and within the separate thread, my Display is created.
Except this is where the problem lies, I have it in a separate thread. So then my program goes on and starts prematurely executing the new StaticShader() which calls even more GL code, breaking the program. (Can't execute before display is created).
What I'm trying to do, is achieve two threads simultaneously which I already have, but make sure that start() method is called completely before anything else is.
Here is how the start method works:
public synchronized void start() {
Threader.createThread(this, "GLDisplay");
}
#Override // public class GLDisplay extends Runnable
public void run() {
// GL code goes here.
}
And here is Threader:
public static void createThread(Runnable behaviour, String name) {
new Thread(behaviour, name + behaviour.hashCode()).start();
}
Now you may notice the synchronized keyword in the start method, well thats just one attempt I've had to no avail. I've also tried the following (which I actually grabbed from another StackOverflow answer):
#Override
public void run() {
synchronized(this) {
// GL code
}
}
I've checked other StackOverflow answers but either don't understand them or don't help me in my case. With the first code block I give in the main method, that is how I want my code to look to the person using it. I'm trying to put the thread-creation inside GlDisplay to hide it.
Any ideas?
Edit:
I can't simply wait for GLDisplay to close either (with Thread.join()) because there lies a while-loop that updates the display for the entirety of the program.
This is the entire reason I multi-threaded it. To allow this forever-ending loop to run while I do other things in the program. By closing the thread, I close the loop, cleanup the display and free the GL context from memory, once again making the shader code fail for lack of an existing context.
You can use java.util.concurrent.CountDownLatch to achieve it which aids in making a thread(s) wait till the operations on other threads is complete. Please see the reference on on what and how to use it.
Example:
public static void main(String[] args) {
CountDownLatch cdl = new CountDownLatch(1);
// pass the CountDownLatch into display
GLDisplay display = new GLDisplay(cdl);
display.start();
// wait for the latch to have been counted down in the disp thread
try
{
cdl.await();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
GLShader shader = new StaticShader();
}
In your GLDisplay thread, call the countDown method of CountDownLatch
I might be misunderstanding something, but try the following:
public static void createThread(Runnable behaviour, String name) {
Thread t = new Thread(behaviour, name + behaviour.hashCode()).start();
t.join();
}
By calling join() the program should wait for the thread to complete.
Well I remember now that I can't have GL code against two separate threads anyway, but thats besides the point.
I don't actually need to use any thread-lock classes or anything, but rather can just do something as simple as this:
private Boolean threadLock = true;
public void start() {
Threader.createThread(this, "GLDisplay");
while (true) {
synchronized(threadLock) {
if (!threadLock) break;
}
}
}
#Runnable
public void run() {
// Do GL code.
synchronized(threadLock) { threadLock = false; }
// Do the rest of whatever I'm doing.
}
When the threadlock is reached in the second thread and is released, the first thread continues doing it's activity. It's that simple!

HealthChecker for Java Process

I want to create a health checker, which will check the health of a java process. My process does a lot of things and is multi threaded. Various exceptions could be thrown, like Service / SQL / IO, etc. My plan is to call the HealthChecker to check for the process, from the catch block, in the individual threads. This will check for all the different healths, and in the case where there is any issue it will pause the threads, and log appropriately. There will be other processes which will read the logs by the process, and alert support to take appropriate actions.
Below is the general structure of the java process.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Schedular {
private static int numOfTasks = 10 ;
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
while(true){
for(int i=0;i<numOfTasks;i++){
service.execute(new Workers());
}
}
}
}
class Workers implements Runnable{
#Override
public void run() {
/*
* This can throw different exceptions , eg:
*/
try{
}catch(Exception e){
e.printStackTrace();
HealthChecker.checkHealth();
}
}
}
class HealthChecker{
public static void checkHealth() {
//Check health and then , log and pause all the threads
}
}
I am not able to figure out a way to pause all the threads. If there is a db exception I want all the threads to pause. I am requesting some suggestions.
You need a way to block the threads until some event occurs that allows the threads to continue. I see some major issues with the code:
1) The while(true) in your main thread might lead to a StackOverflowError. With each iteration of the while loop, you will add 10 more threads to the executor, and this will just continue unbounded.
2) There is no loop in your run() so that even if an exception is caught and we wait for the HealthCheck, the run() method would still exit. While a loop is not needed in your run() if you can constantly execute new Threads from your main thread to take the place of the terminated one, but that logic is not presently there in the main loop.
But setting those concerns aside here is one way to block worker threads until some event (presumably a HealthCheck all clear) occurs.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Schedular {
private static int numOfTasks = 10 ;
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
HealtchChecker hChecker = new HealthChecker();
for(int i=0;i<numOfTasks;i++){
service.execute(new Workers(hChecker));
}
}
}
class Workers implements Runnable{
private HealtchChecker hChecker;
public Workers(HealtchChecker hChecker){
this.hChecker = hChecker;
}
#Override
public void run() {
/*
* This can throw different exceptions , eg:
*/
while(true) {
try{
}catch (InterruptedException ie) {
throw ie;
}catch(Exception e){
e.printStackTrace();
HealthChecker.checkHealth();
}
}
}
}
class HealthChecker implements Runnable {
private final Semaphore semaphore = new Semaphore(1, true);
public void checkHealth() {
try {
semaphore.acquire();
} finally {
semaphore.release();
}
}
#Override
public void run(){
//code to check for errors that cause threads to pause.
if (inErrorState) {
semaphore.acquire();
} else {
semaphore.release();
}
}
}
A few things worth mentioning.
1) The main thread only creates 10 threads, versus an unbounded amount. You can adjust this as needed.
2) The Worker thread is long lived, meaning it will continue running even if it encounters Exceptions, except for an InterruptException.
3) HealthCheck is no longer a static object. it is instead a shared object.
4) HealthCheck is a runnable that can be executed in its own thread for monitoring for errors. I did not add the code to execute this thread.
5) HealCheck uses a Semaphore to cause the threads to block until the error state is cleared. I looked for other objects that can do this, like CountDownLatch or CyclicBarrier or Phaser, but this one came closest to giving us what we need to block all the threads from one point (the run() method).
Its not perfect but I think it gets you a little bit closer to what you want.
You're venturing pretty far afield from best practices, but you didn't ask about best practices for monitoring the health of threads - so I won't answer that question. Instead, I'll just answer the question you asked: how can I pause a set of threads managed by an ExecutorService?
Assuming that your Workers.run() will eventually end without intervention (in other words, it's not in an infinite loop - intentional or otherwise), the right thing to do is to call service.shutdown() (where service is your instance of ExecutorService). To do this, you can pass service in to HealthCheck.healthCheck() as a new parameter. Calling shutdown() will allow the currently-running threads to complete, then stop the executor.
If Workers.run() will not naturally complete, best practice says that you need to change your code such that it will. There is a Thread.stop() method you can call to halt the thread and a Thread.suspend() method you can call to suspend the thread. Both of these are double-bad ideas for you to use for two reasons:
They are Deprecated and will leave the Threads in a super-unhealthy state. You will have very difficult problems in the future if you use them.
You are using ExecutorService. That means you are delegating thread management to that class. If you go messing with the state of the Threads underneath ExecutorService, it can't manage the thread pool for you and, again, you will have very difficult problems in the future.

How to run a program forever in Java? Is System.in.read() the only way?

I took this code:
28 public static void main(String[] args) throws IOException {
29 HttpServer httpServer = startServer();
30 System.out.println(String.format("Jersey app started with WADL available at "
31 + "%sapplication.wadl\nTry out %shelloworld\nHit enter to stop it...",
32 BASE_URI, BASE_URI));
33 System.in.read();
34 httpServer.stop();
35 }
Does line 33 "System.in.read()" means that it will block until there is input? Will this also work when starting the Java application using UNIX rc script - not manually started from a command line?
I'd like to write a Java application to listen for HTTP connections. The application will be started automatically when the system boots (using UNIX rc scripts). It means that the application will run continuously - theoretically forever, until purposefully stopped. What is the best way to implement this in the Java main() method?
It looks like a weird black magic but following does the trick in very elegant way
Thread.currentThread().join();
As a result the current thread, main for instance, waits on join() for thread main, that is itself, to end. Deadlocked.
The blocked thread must not be a daemon thread of course.
Leaving the main method in Java does not automatically end the program.
The JVM exists if no more non-daemon threads are running. By default the only non-daemon thread is the main thread and it ends when you leave the main method, therefore stopping the JVM.
So either don't end the main thread (by not letting the main method return) or create a new non-daemon thread that never returns (at least not until you want the JVM to end).
Since that rule is actually quite sensible there is usually a perfect candidate for such a thread. For a HTTP server, for example that could be the thread that actually accepts connections and hands them off to other threads for further processing. As long as that code is running, the JVM will continue running, even if the main method has long since finished running.
#Joachim's answer is correct.
But if (for some reason) you still want to block the main method indefinitely (without polling), then you can do this:
public static void main(String[] args) {
// Set up ...
try {
Object lock = new Object();
synchronized (lock) {
while (true) {
lock.wait();
}
}
} catch (InterruptedException ex) {
}
// Do something after we were interrupted ...
}
Since the lock object is only visible to this method, nothing can notify it, so the wait() call won't return. However, some other thread could still unblock the main thread ... by interrupting it.
while (true) { ... } should go on for a pretty long time. Of course, you'll have to figure out some way of stopping it eventually.
A common trick is to have some volatile boolean running = true, then have the main loop be while (running) { ... } and define some criteria by which a thread sets running = false.
Back to Threads, thats exactly what i wanted. Btw this awesome tutorial helped me a lot.
Main.java
public class Main {
public static void main(String args[]) {
ChatServer server = null;
/*if (args.length != 1)
System.out.println("Usage: java ChatServer port");
else*/
server = new ChatServer(Integer.parseInt("8084"));
}
}
and ChatServer.java Class extends a Runnable
public class ChatServer implements Runnable
{ private ChatServerThread clients[] = new ChatServerThread[50];
private ServerSocket server = null;
private Thread thread = null;
private int clientCount = 0;
public ChatServer(int port)
{ try
{ System.out.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
start(); }
catch(IOException ioe)
{
System.out.println("Can not bind to port " + port + ": " + ioe.getMessage()); }
}
public void start() {
if (thread == null) {
thread = new Thread(this);
thread.start();
}
}
.... pleas continue with the tutorial
So in the main Method a Runnable is being instantiated and a new Thread as shown in
public void start() {
is being instantiated with the runnable.
That cases the JVM to continue executing the process until you quit the project or the debugger.
Btw thats the same as Joachim Sauer posted in his answere.
Java program terminates when there are no non-daemon threads running. All you need is to have one such running thread. You could do it using infinite loops but that would consume CPU cycles. The following seems like a reasonable way to do it.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {}); //submit a task that does what you want (in this case, nothing)
Also we can achieve the same with the ReentrantLock and call wait() on it:
public class Test{
private static Lock mainThreadLock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
System.out.println("Stop me if you can");
synchronized (mainThreadLock) {
mainThreadLock.wait();
}
}

How do you kill a Thread in Java?

How do you kill a java.lang.Thread in Java?
See this thread by Sun on why they deprecated Thread.stop(). It goes into detail about why this was a bad method and what should be done to safely stop threads in general.
The way they recommend is to use a shared variable as a flag which asks the background thread to stop. This variable can then be set by a different object requesting the thread terminate.
Generally you don't..
You ask it to interrupt whatever it is doing using Thread.interrupt() (javadoc link)
A good explanation of why is in the javadoc here (java technote link)
In Java threads are not killed, but the stopping of a thread is done in a cooperative way. The thread is asked to terminate and the thread can then shutdown gracefully.
Often a volatile boolean field is used which the thread periodically checks and terminates when it is set to the corresponding value.
I would not use a boolean to check whether the thread should terminate. If you use volatile as a field modifier, this will work reliable, but if your code becomes more complex, for instead uses other blocking methods inside the while loop, it might happen, that your code will not terminate at all or at least takes longer as you might want.
Certain blocking library methods support interruption.
Every thread has already a boolean flag interrupted status and you should make use of it. It can be implemented like this:
public void run() {
try {
while (!interrupted()) {
// ...
}
} catch (InterruptedException consumed)
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
Source code adapted from Java Concurrency in Practice. Since the cancel() method is public you can let another thread invoke this method as you wanted.
One way is by setting a class variable and using it as a sentinel.
Class Outer {
public static volatile flag = true;
Outer() {
new Test().start();
}
class Test extends Thread {
public void run() {
while (Outer.flag) {
//do stuff here
}
}
}
}
Set an external class variable, i.e. flag = true in the above example. Set it to false to 'kill' the thread.
I want to add several observations, based on the comments that have accumulated.
Thread.stop() will stop a thread if the security manager allows it.
Thread.stop() is dangerous. Having said that, if you are working in a JEE environment and you have no control over the code being called, it may be necessary; see Why is Thread.stop deprecated?
You should never stop stop a container worker thread. If you want to run code that tends to hang, (carefully) start a new daemon thread and monitor it, killing if necessary.
stop() creates a new ThreadDeathError error on the calling thread and then throws that error on the target thread. Therefore, the stack trace is generally worthless.
In JRE 6, stop() checks with the security manager and then calls stop1() that calls stop0(). stop0() is native code.
As of Java 13 Thread.stop() has not been removed (yet), but Thread.stop(Throwable) was removed in Java 11. (mailing list, JDK-8204243)
There is a way how you can do it. But if you had to use it, either you are a bad programmer or you are using a code written by bad programmers. So, you should think about stopping being a bad programmer or stopping using this bad code.
This solution is only for situations when THERE IS NO OTHER WAY.
Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );
I'd vote for Thread.stop().
As for instance you have a long lasting operation (like a network request).
Supposedly you are waiting for a response, but it can take time and the user navigated to other UI.
This waiting thread is now a) useless b) potential problem because when he will get result, it's completely useless and he will trigger callbacks that can lead to number of errors.
All of that and he can do response processing that could be CPU intense. And you, as a developer, cannot even stop it, because you can't throw if (Thread.currentThread().isInterrupted()) lines in all code.
So the inability to forcefully stop a thread it weird.
The question is rather vague. If you meant “how do I write a program so that a thread stops running when I want it to”, then various other responses should be helpful. But if you meant “I have an emergency with a server I cannot restart right now and I just need a particular thread to die, come what may”, then you need an intervention tool to match monitoring tools like jstack.
For this purpose I created jkillthread. See its instructions for usage.
There is of course the case where you are running some kind of not-completely-trusted code. (I personally have this by allowing uploaded scripts to execute in my Java environment. Yes, there are security alarm bell ringing everywhere, but it's part of the application.) In this unfortunate instance you first of all are merely being hopeful by asking script writers to respect some kind of boolean run/don't-run signal. Your only decent fail safe is to call the stop method on the thread if, say, it runs longer than some timeout.
But, this is just "decent", and not absolute, because the code could catch the ThreadDeath error (or whatever exception you explicitly throw), and not rethrow it like a gentlemanly thread is supposed to do. So, the bottom line is AFAIA there is no absolute fail safe.
'Killing a thread' is not the right phrase to use. Here is one way we can implement graceful completion/exit of the thread on will:
Runnable which I used:
class TaskThread implements Runnable {
boolean shouldStop;
public TaskThread(boolean shouldStop) {
this.shouldStop = shouldStop;
}
#Override
public void run() {
System.out.println("Thread has started");
while (!shouldStop) {
// do something
}
System.out.println("Thread has ended");
}
public void stop() {
shouldStop = true;
}
}
The triggering class:
public class ThreadStop {
public static void main(String[] args) {
System.out.println("Start");
// Start the thread
TaskThread task = new TaskThread(false);
Thread t = new Thread(task);
t.start();
// Stop the thread
task.stop();
System.out.println("End");
}
}
There is no way to gracefully kill a thread.
You can try to interrupt the thread, one commons strategy is to use a poison pill to message the thread to stop itself
public class CancelSupport {
public static class CommandExecutor implements Runnable {
private BlockingQueue<String> queue;
public static final String POISON_PILL = “stopnow”;
public CommandExecutor(BlockingQueue<String> queue) {
this.queue=queue;
}
#Override
public void run() {
boolean stop=false;
while(!stop) {
try {
String command=queue.take();
if(POISON_PILL.equals(command)) {
stop=true;
} else {
// do command
System.out.println(command);
}
} catch (InterruptedException e) {
stop=true;
}
}
System.out.println(“Stopping execution”);
}
}
}
BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);
http://anandsekar.github.io/cancel-support-for-threads/
Generally you don't kill, stop, or interrupt a thread (or check wheter it is interrupted()), but let it terminate naturally.
It is simple. You can use any loop together with (volatile) boolean variable inside run() method to control thread's activity. You can also return from active thread to the main thread to stop it.
This way you gracefully kill a thread :) .
Attempts of abrupt thread termination are well-known bad programming practice and evidence of poor application design. All threads in the multithreaded application explicitly and implicitly share the same process state and forced to cooperate with each other to keep it consistent, otherwise your application will be prone to the bugs which will be really hard to diagnose. So, it is a responsibility of developer to provide an assurance of such consistency via careful and clear application design.
There are two main right solutions for the controlled threads terminations:
Use of the shared volatile flag
Use of the pair of Thread.interrupt() and Thread.interrupted() methods.
Good and detailed explanation of the issues related to the abrupt threads termination as well as examples of wrong and right solutions for the controlled threads termination can be found here:
https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads
Here are a couple of good reads on the subject:
What Do You Do With InterruptedException?
Shutting down threads cleanly
I didn't get the interrupt to work in Android, so I used this method, works perfectly:
boolean shouldCheckUpdates = true;
private void startupCheckForUpdatesEveryFewSeconds() {
Thread t = new Thread(new CheckUpdates());
t.start();
}
private class CheckUpdates implements Runnable{
public void run() {
while (shouldCheckUpdates){
//Thread sleep 3 seconds
System.out.println("Do your thing here");
}
}
}
public void stop(){
shouldCheckUpdates = false;
}
Thread.stop is deprecated so how do we stop a thread in java ?
Always use interrupt method and future to request cancellation
When the task responds to interrupt signal, for example, blocking queue take method.
Callable < String > callable = new Callable < String > () {
#Override
public String call() throws Exception {
String result = "";
try {
//assume below take method is blocked as no work is produced.
result = queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return result;
}
};
Future future = executor.submit(callable);
try {
String result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
logger.error("Thread timedout!");
return "";
} finally {
//this will call interrupt on queue which will abort the operation.
//if it completes before time out, it has no side effects
future.cancel(true);
}
When the task does not respond to interrupt signal.Suppose the task performs socket I/O which does not respond to interrupt signal and thus using above approach will not abort the task, future would time out but the cancel in finally block will have no effect, thread will keep on listening to socket. We can close the socket or call close method on connection if implemented by pool.
public interface CustomCallable < T > extends Callable < T > {
void cancel();
RunnableFuture < T > newTask();
}
public class CustomExecutorPool extends ThreadPoolExecutor {
protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) {
if (callable instanceof CancellableTask)
return ((CancellableTask < T > ) callable).newTask();
else
return super.newTaskFor(callable);
}
}
public abstract class UnblockingIOTask < T > implements CustomCallable < T > {
public synchronized void cancel() {
try {
obj.close();
} catch (IOException e) {
logger.error("io exception", e);
}
}
public RunnableFuture < T > newTask() {
return new FutureTask < T > (this) {
public boolean cancel(boolean mayInterruptIfRunning) {
try {
this.cancel();
} finally {
return super.cancel(mayInterruptIfRunning);
}
}
};
}
}
After 15+ years of developing in Java there is one thing I want to say to the world.
Deprecating Thread.stop() and all the holy battle against its use is just another bad habit or design flaw unfortunately became a reality... (eg. want to talk about the Serializable interface?)
The battle is focusing on the fact that killing a thread can leave an object into an inconsistent state. And so? Welcome to multithread programming. You are a programmer, and you need to know what you are doing, and yes.. killing a thread can leave an object in inconsistent state. If you are worried about it use a flag and let the thread quit gracefully; but there are TONS of times where there is no reason to be worried.
But no.. if you type thread.stop() you're likely to be killed by all the people who looks/comments/uses your code. So you have to use a flag, call interrupt(), place if(!flag) all around your code because you're not looping at all, and finally pray that the 3rd-party library you're using to do your external call is written correctly and doesn't handle the InterruptException improperly.

Categories