Stop Java Draw

This may be the case when I just do not understand what I read, but all the examples for killing a thread in Java seem to indicate that you need to signal a thread to kill yourself; you cannot kill him from without without any serious risks. The problem is that all examples of how to “politely” ask a thread to die have some kind of cycle, so all you have to do is keep an eye on the flag at each iteration.

So, I have a thread that does something that takes some time (a series of SQL queries). Of course, it’s possible for me to simply check the check after each step, but they are not in a loop, and I’m not a very elegant way that I know to get around this. Here is an example of what I am doing:

new Thread(new Runnable(){ public void run(){ //query 1 Connection conn = db.getConnection(); Statement s = conn.createStatement(); ResultSet rs = s.executeQuery("SELECT ..."); while(rs.next()){ //do stuff } //query 2 rs = s.executeQuery("SELECT ..."); while(rs.next()){ //do stuff } //query 3 rs = s.executeQuery("SELECT ..."); while(rs.next()){ //do stuff } } }).start(); 

This is an example, I do not use anonymous inner classes, but it shows that my run () method cannot stop elegantly. Moreover, even I check after each step, if a particular request takes a very long time to run, this code will not be able to stop until the request is completed.

This code is for a GUI application, and I'd really like to find a good way to quickly kill a thread without using Thread.stop ().

EDIT - yshavit's answer was a big help as I did not know that Statement.cancel() existed. If you're interested, the answer to my specific problem was to create a more abstract database access class. The class had to create a child thread to execute the query and loop during its launch, checking each iteration if the current thread (and not the child) was interrupted. If it is interrupted, it simply calls Statement.cancel (), and the child thread will throw an exception and die. Not all JDBC drivers support Statement.cancel() , but Oracle 11g does.

+7
source share
5 answers

Find out what is required and cancel it. If what takes the most time is the rs.next() loops, you can do:

 while(rs.next()){ if (myVolatileBooleanSaysToStop) { return; // or whatever } //do stuff } 

If those things that take time are instructions, and your JDBC driver / server supports Statement.cancel , you can post your Statement to the second thread, which is responsible for calling Statement.cancel , if necessary. I am not sure, but I think that this will cause the driver to be a SQLException , and you can somehow identify yourself as refusing to cancel and handle it accordingly.

In addition, you should consider reorganizing. You have three pieces of “run the query, iterate over its results”, which can be taken into account in the method (which will then take care of closing the statement, etc.).

+4
source

If you do not want to implement your own thread.kill () mechanism from scratch, you can use the existing API, control the creation of threads in ThreadPoolExecutor, and use Future.cancel () to kill the current thread:

 ThreadPoolExecutor threadPoolExecutor = Executors.newSingleThreadExecutor(); Runnable longRunningTask = new Runnable(); // submit task to threadpool: Future longRunningTaskFuture = threadPoolExecutor.submit(longRunningTask); ... ... // At some point in the future, if you want to kill the task: longRunningTaskFuture.cancel(true); ... ... 

The method will be canceled differently depending on the state of your task; check the API for more details.

+1
source

The Java thread will close after shutting down (). If you run () in a loop, exit the loop, Thread.run will end, and the thread will die. You can also use return; , if I'm not mistaken.

0
source

To interrupt a client thread (i.e. code that runs outside the thread):

 threadInstance.interrupt(); 

To check if the thread your code is running on was interrupted:

 Thread.currentThread().isInterrupted() 

Another option is to try to sleep:

 Thread.currentThread().sleep(1) 

What is nice for sleeping is an exception if the thread has been interrupted (i.e. InterruptedException). Therefore, it is important not to ignore these exceptions.

You can add checks inside while loops using Thread.currentThread (). isInterrupted (), or you can check sleep (1) between statements. I would not sleep in a loop, as this will really slow down your code. Here is where the hybrid approach might be best:

 if( Thread.currentThread().isInterrupted() ) throw new InterruptedException(); 

Then you will catch this as part of the run () method and stop.

The bottom line is that you should periodically check if the external client has requested a shutdown. If there were 6 operators in the stream. Enabling checks between these statements will allow your thread to exit.

 public run() { try { doSomething(); if( Thread.currentInstance().isInterrupted() ) throw new InterruptException(); doNextSomething(); if( Thread.currentInstance().isInterrupted() ) throw new InterruptException(); doSomeMoreThings(); if( Thread.currentInstance().isInterrupted() ) throw new InterruptException(); doYetMoreThings(); } catch( InterruptedException e ) { System.out.println("Duff man going down."); } } 

In fact, there is no difference between doing this and putting one check in a loop.

0
source

If you do not want to interrupt the stream, the only option is to somehow kill / cancel the long request. If you can run the async request, you can just wait until the results are ready or you get a signal to die, but you cannot call jnbc async .

0
source

All Articles