plaskowj
asked on
Stop a thread mid execution
can anyone tell me how to stop a thread mid execution?
e.g.
the thread goes into an infinate loop
how can i get its parent to stop it?
e.g.
the thread goes into an infinate loop
how can i get its parent to stop it?
Could you post ur code.
ASKER
you can see that myThread.run(0 is call doSomething - which goes ionto an infinate loop- how can i break that loop, from outside the thread?
public class myThread extends Thread{
public myThread(){
}
public synchronized void run{
doSomething();
}
public void doSomething(){
for (;;)
system.out.println("recurs ive"):
}
}
public class myThread extends Thread{
public myThread(){
}
public synchronized void run{
doSomething();
}
public void doSomething(){
for (;;)
system.out.println("recurs
}
}
>>>goes into an infinate loop
what do you exactly mean by this, I think that I solved ur problem at your wait() question. Clarify what u want with some code preferably.
what do you exactly mean by this, I think that I solved ur problem at your wait() question. Clarify what u want with some code preferably.
ASKER
well the point is - what actually happens in my thread is that I call a url
and open the stream - if by anychance the stream is hanging, i have a timer which pops up and alerts program to say that request is hanging to long - kill
So i want to know how to kill the request
and open the stream - if by anychance the stream is hanging, i have a timer which pops up and alerts program to say that request is hanging to long - kill
So i want to know how to kill the request
from Bruce Eckel's TiJ
There are times when a thread blocks, such as when it is waiting for input, and it cannot poll a flag as it does in Blocking.java. In these cases, you still shouldn’t use stop( ), but instead you can use the interrupt( ) method in Thread to break out of the blocked code:
//: Interrupt.java
// The alternative approach to using stop()
// when a thread is blocked
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
class Blocked extends Thread {
public synchronized void run() {
try {
wait(); // Blocks simluate a IO block
} catch(InterruptedException e) {
System.out.println("Interr uptedExcep tion");
}
System.out.println("Exitin g run()");
}
}
public class Interrupt extends Applet {
private Button
interrupt = new Button("Interrupt");
private Blocked blocked = new Blocked();
public void init() {
add(interrupt);
interrupt.addActionListene r(
new ActionListener() {
public
void actionPerformed(ActionEven t e) {
System.out.println("Button pressed");
if(blocked == null) return;
Thread remove = blocked;
blocked = null; // to release it
remove.interrupt();
}
});
blocked.start();
}
public static void main(String[] args) {
Interrupt applet = new Interrupt();
Frame aFrame = new Frame("Interrupt");
aFrame.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
aFrame.add(applet, BorderLayout.CENTER);
aFrame.setSize(200,100);
applet.init();
applet.start();
aFrame.setVisible(true);
}
} ///:~
The wait( ) inside Blocked.run( ) produces the blocked thread. When you press the button, the blocked handle is set to null so the garbage collector will clean it up, and then the object’s interrupt( ) method is called. The first time you press the button you’ll see that the thread quits, but after that there’s no thread to kill so you just see that the button has been pressed.
There are times when a thread blocks, such as when it is waiting for input, and it cannot poll a flag as it does in Blocking.java. In these cases, you still shouldn’t use stop( ), but instead you can use the interrupt( ) method in Thread to break out of the blocked code:
//: Interrupt.java
// The alternative approach to using stop()
// when a thread is blocked
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
class Blocked extends Thread {
public synchronized void run() {
try {
wait(); // Blocks simluate a IO block
} catch(InterruptedException
System.out.println("Interr
}
System.out.println("Exitin
}
}
public class Interrupt extends Applet {
private Button
interrupt = new Button("Interrupt");
private Blocked blocked = new Blocked();
public void init() {
add(interrupt);
interrupt.addActionListene
new ActionListener() {
public
void actionPerformed(ActionEven
System.out.println("Button
if(blocked == null) return;
Thread remove = blocked;
blocked = null; // to release it
remove.interrupt();
}
});
blocked.start();
}
public static void main(String[] args) {
Interrupt applet = new Interrupt();
Frame aFrame = new Frame("Interrupt");
aFrame.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
aFrame.add(applet, BorderLayout.CENTER);
aFrame.setSize(200,100);
applet.init();
applet.start();
aFrame.setVisible(true);
}
} ///:~
The wait( ) inside Blocked.run( ) produces the blocked thread. When you press the button, the blocked handle is set to null so the garbage collector will clean it up, and then the object’s interrupt( ) method is called. The first time you press the button you’ll see that the thread quits, but after that there’s no thread to kill so you just see that the button has been pressed.
note ur example of showing system.out.println("recurs ive"):
is not true in most cases ,in the real world the situation is more like wait() as outlined above.
is not true in most cases ,in the real world the situation is more like wait() as outlined above.
ASKER
thats ok, but a compiler won't let you put a try catch InterruptedException around any code - it has to have a wait - and in the real world i wouldn't be using wait
>>>but a compiler won't let you put a try catch InterruptedException around any code -
but it will allow you catch(Exception)
>>>and in the real world i wouldn't be using wait
I know but a block is best simulated by a wait() wherever or whichever code you read in,pls try and do so ,u will never see sleep(10) or something like that as it wastes CPU resources,the thread wakes up everytime it's time limit has expired ,but in case of wait() it wakes up only when notified.
plaskowj,
You already have BusyFlag.java,AsyncInputSt ream.java in ur other questoion and here is the third class to complete the loop ,CondVar.java which will do EXACTLY the same thing as you want it has a timed wait() which you can supply,I do hope that now all your problems will be solved.
public class CondVar {
private BusyFlag SyncVar;
public CondVar() {
this(new BusyFlag());
}
public CondVar(BusyFlag sv) {
SyncVar = sv;
}
public void cvWait() throws InterruptedException {
cvTimedWait(SyncVar, 0);
}
public void cvWait(BusyFlag sv) throws InterruptedException {
cvTimedWait(sv, 0);
}
public void cvTimedWait(int millis) throws InterruptedException {
cvTimedWait(SyncVar, millis);
}
public void cvTimedWait(BusyFlag sv, int millis) throws InterruptedException {
int i = 0;
InterruptedException errex = null;
synchronized (this) {
// You must own the lock in order to use this method
if (sv.getBusyFlagOwner() != Thread.currentThread()) {
throw new IllegalMonitorStateExcepti on("curren t thread not owner");
}
// Release the lock (Completely)
while (sv.getBusyFlagOwner() == Thread.currentThread()) {
i++;
sv.freeBusyFlag();
}
// Use wait() method
try {
if (millis == 0) {
wait();
} else {
wait(millis);
}
} catch (InterruptedException iex) {
errex = iex;
}
}
// Obtain the lock (Return to original state)
for (; i>0; i--) {
sv.getBusyFlag();
}
if (errex != null) throw errex;
return;
}
public void cvSignal() {
cvSignal(SyncVar);
}
public synchronized void cvSignal(BusyFlag sv) {
// You must own the lock in order to use this method
if (sv.getBusyFlagOwner() != Thread.currentThread()) {
throw new IllegalMonitorStateExcepti on("curren t thread not owner");
}
notify();
}
public void cvBroadcast() {
cvBroadcast(SyncVar);
}
public synchronized void cvBroadcast(BusyFlag sv) {
// You must own the lock in order to use this method
if (sv.getBusyFlagOwner() != Thread.currentThread()) {
throw new IllegalMonitorStateExcepti on("curren t thread not owner");
}
notifyAll();
}
}
but it will allow you catch(Exception)
>>>and in the real world i wouldn't be using wait
I know but a block is best simulated by a wait() wherever or whichever code you read in,pls try and do so ,u will never see sleep(10) or something like that as it wastes CPU resources,the thread wakes up everytime it's time limit has expired ,but in case of wait() it wakes up only when notified.
plaskowj,
You already have BusyFlag.java,AsyncInputSt
public class CondVar {
private BusyFlag SyncVar;
public CondVar() {
this(new BusyFlag());
}
public CondVar(BusyFlag sv) {
SyncVar = sv;
}
public void cvWait() throws InterruptedException {
cvTimedWait(SyncVar, 0);
}
public void cvWait(BusyFlag sv) throws InterruptedException {
cvTimedWait(sv, 0);
}
public void cvTimedWait(int millis) throws InterruptedException {
cvTimedWait(SyncVar, millis);
}
public void cvTimedWait(BusyFlag sv, int millis) throws InterruptedException {
int i = 0;
InterruptedException errex = null;
synchronized (this) {
// You must own the lock in order to use this method
if (sv.getBusyFlagOwner() != Thread.currentThread()) {
throw new IllegalMonitorStateExcepti
}
// Release the lock (Completely)
while (sv.getBusyFlagOwner() == Thread.currentThread()) {
i++;
sv.freeBusyFlag();
}
// Use wait() method
try {
if (millis == 0) {
wait();
} else {
wait(millis);
}
} catch (InterruptedException iex) {
errex = iex;
}
}
// Obtain the lock (Return to original state)
for (; i>0; i--) {
sv.getBusyFlag();
}
if (errex != null) throw errex;
return;
}
public void cvSignal() {
cvSignal(SyncVar);
}
public synchronized void cvSignal(BusyFlag sv) {
// You must own the lock in order to use this method
if (sv.getBusyFlagOwner() != Thread.currentThread()) {
throw new IllegalMonitorStateExcepti
}
notify();
}
public void cvBroadcast() {
cvBroadcast(SyncVar);
}
public synchronized void cvBroadcast(BusyFlag sv) {
// You must own the lock in order to use this method
if (sv.getBusyFlagOwner() != Thread.currentThread()) {
throw new IllegalMonitorStateExcepti
}
notifyAll();
}
}
read() in AsyncInputStream.java is defined as
public int read() throws IOException {
try {
lock.getBusyFlag();
while (reslen == 0) {
try {
if (EOF) return(-1);
if (IOError != null) throw IOError;
empty.cvWait();
} catch (InterruptedException e) {}
}
return (int) getChar();
} finally {
lock.freeBusyFlag();
}
}
look at empty.cvWait(); which is NOT a timed wait but you may want to change it to something else like
empty.cvTimedWait(100000); //100 seconds timeout .....
public int read() throws IOException {
try {
lock.getBusyFlag();
while (reslen == 0) {
try {
if (EOF) return(-1);
if (IOError != null) throw IOError;
empty.cvWait();
} catch (InterruptedException e) {}
}
return (int) getChar();
} finally {
lock.freeBusyFlag();
}
}
look at empty.cvWait(); which is NOT a timed wait but you may want to change it to something else like
empty.cvTimedWait(100000);
Well you could set a "busy flag" from outside your thread that seems to hang,And then poll for this flag within your infinite loop in your thread.
Once you find that the busy flag has been set.Simply stop the execution of the thread.
Once you find that the busy flag has been set.Simply stop the execution of the thread.
>>>Well you could set a "busy flag" from outside your thread that seems to hang,And then poll for this flag within your infinite loop in your thread.
Once you find that the busy flag has been set.Simply stop the execution of the thread.
Generally the thread is in wait() when it 'hangs' so it cant detect changes in the flag,u have to use notify().
plaskowj,
to repeat again in the read() of AsyncInputStream.java catch the InterruptedException and return -1 to indicate EOF ,dont shut it up like its done now.i.e
instead of catch (InterruptedException e) {}
use
catch (InterruptedException e)
{
EOF = true;// Mark End Of File
}
this is the only good clean way to terminate the 'hanging' thread
Once you find that the busy flag has been set.Simply stop the execution of the thread.
Generally the thread is in wait() when it 'hangs' so it cant detect changes in the flag,u have to use notify().
plaskowj,
to repeat again in the read() of AsyncInputStream.java catch the InterruptedException and return -1 to indicate EOF ,dont shut it up like its done now.i.e
instead of catch (InterruptedException e) {}
use
catch (InterruptedException e)
{
EOF = true;// Mark End Of File
}
this is the only good clean way to terminate the 'hanging' thread
no respones from u?
I dont think his thread is in a wait() state cause he clearly says that he is in an infinite loop.
Anyhow plaskowj....what exactly do you mean by an "infinite loop"
is it an infinite loop as in a while true loop or have you made a blocking call somewhere that causes the thread to "hang"??
Anyhow plaskowj....what exactly do you mean by an "infinite loop"
is it an infinite loop as in a while true loop or have you made a blocking call somewhere that causes the thread to "hang"??
I am pasting some ready made code here which you can use duirectly for Socket as it isthe class which I have used extensively ,See you on Monday
Please test it out ...
public class AsyncReadBuffer
{
private StringBuffer result;
public AsyncReadBuffer()
{
result = new StringBuffer(500);
}
//Get the string already read from the socket so far.
//This method is used by the Applet or external thread
//to obtain the data in a synchronous manner.
public synchronized String getResult()
{
String retval = result.toString();
result.setLength(0);
return retval;
}
//Put new data into the buffer to be returned
//by the getResult method
public synchronized void update(char c)
{
result.append(c);
}
public synchronized void update(String s)
{
result.append(s);
}
}
import java.util.*;
import java.io.*;
import java.net.*;
public class ClientHandler extends Thread
{
private BufferedReader buff;
private Socket sock;
private AsyncReadBuffer aReader;
private boolean isDone = false;
private Object lock = new Object();
private int timeout;
private boolean isReadLineMode=false;
class ClientHandlerThread extends Thread
{
public void run()
{
String s;
int c;
try
{
if(isReadLineMode)
{
while ((s = buff.readLine()) != null)
aReader.update(s);
}
else
{
while ((c = buff.read()) != -1)
aReader.update((char)c);
}
}
catch (Exception e)
{}
isDone = true;
synchronized(lock)
{
lock.notify();
}
}
}
public ClientHandler(AsyncReadBuf fer a, Socket s,int t,boolean isReadLine)throws Exception
{
this.aReader=a;
this.sock=s;
this.isReadLineMode=isRead Line;
if(t<0 || t==Integer.MAX_VALUE)
throw new Exception("Specify correct timeout value");
this.timeout=t;
}
public void run()
{
try
{
this.buff = new BufferedReader(new InputStreamReader(sock.get InputStrea m()));
Thread t = new ClientHandlerThread();
t.start();
synchronized(lock)
{
while (!isDone)
{
try
{
lock.wait(this.timeout);
}
catch (InterruptedException ie)
{
isDone = true;
try
{
t.interrupt();
this.buff.close();this.buf f=null;
this.sock.close();this.soc k=null;
}
catch (Exception e)
{}
}
}
}
}
catch(Throwable t)
{
System.out.println("Caught Exception during run() in timeout main thread");
t.printStackTrace();
}
}
}
Please test it out ...
public class AsyncReadBuffer
{
private StringBuffer result;
public AsyncReadBuffer()
{
result = new StringBuffer(500);
}
//Get the string already read from the socket so far.
//This method is used by the Applet or external thread
//to obtain the data in a synchronous manner.
public synchronized String getResult()
{
String retval = result.toString();
result.setLength(0);
return retval;
}
//Put new data into the buffer to be returned
//by the getResult method
public synchronized void update(char c)
{
result.append(c);
}
public synchronized void update(String s)
{
result.append(s);
}
}
import java.util.*;
import java.io.*;
import java.net.*;
public class ClientHandler extends Thread
{
private BufferedReader buff;
private Socket sock;
private AsyncReadBuffer aReader;
private boolean isDone = false;
private Object lock = new Object();
private int timeout;
private boolean isReadLineMode=false;
class ClientHandlerThread extends Thread
{
public void run()
{
String s;
int c;
try
{
if(isReadLineMode)
{
while ((s = buff.readLine()) != null)
aReader.update(s);
}
else
{
while ((c = buff.read()) != -1)
aReader.update((char)c);
}
}
catch (Exception e)
{}
isDone = true;
synchronized(lock)
{
lock.notify();
}
}
}
public ClientHandler(AsyncReadBuf
{
this.aReader=a;
this.sock=s;
this.isReadLineMode=isRead
if(t<0 || t==Integer.MAX_VALUE)
throw new Exception("Specify correct timeout value");
this.timeout=t;
}
public void run()
{
try
{
this.buff = new BufferedReader(new InputStreamReader(sock.get
Thread t = new ClientHandlerThread();
t.start();
synchronized(lock)
{
while (!isDone)
{
try
{
lock.wait(this.timeout);
}
catch (InterruptedException ie)
{
isDone = true;
try
{
t.interrupt();
this.buff.close();this.buf
this.sock.close();this.soc
}
catch (Exception e)
{}
}
}
}
}
catch(Throwable t)
{
System.out.println("Caught
t.printStackTrace();
}
}
}
I have adapted it from the book after careful study ,had a long night so have no time to test it throughly,but please give feedback as this is the class which I am going to use myself for all my Threaded I/O stuff.
If you notice carefully,have included all previous suggestions of mine into these 2 classes
Regards
If you notice carefully,have included all previous suggestions of mine into these 2 classes
Regards
I learnt 1 thing today that if you have to close the socket read/write
you have to close() the underlying input/output stream.
Get a reference like
InputStream in=sock.getInputStream();
Use in program like
BufferedReader buff = new BufferedReader(new InputStreamReader(sock.get InputStrea m()));
The reason is that both read() and close() are synchronized in
Wrapper classes like BufferedReader & BufferedInputStream in JDK 1.2
& up ,so this above program will only work in JDK 1.1.
Translated into simpler terms when you call close() ,it will block
forever.
So use
in.close() instead of buff.close()
you have to close() the underlying input/output stream.
Get a reference like
InputStream in=sock.getInputStream();
Use in program like
BufferedReader buff = new BufferedReader(new InputStreamReader(sock.get
The reason is that both read() and close() are synchronized in
Wrapper classes like BufferedReader & BufferedInputStream in JDK 1.2
& up ,so this above program will only work in JDK 1.1.
Translated into simpler terms when you call close() ,it will block
forever.
So use
in.close() instead of buff.close()
no input from your side?
ASKER
The truth is in the end, I have a timer on the thread, if a period of time elapses, i a create a new thread which controls i/o, and ignore the other. I know this is not a great solution, but it is one satisfactory at the mo.
I don't get you ,how did you solve that ? Please tell inb detail so I can understand?
ASKER
what i did was use a timer, if the timer elapses then i ignore the thread and crate a new one in its place
that is very bad design practice ,tell me if ur thread is blocking forever how many threads will u create?
Why dont u try the solution I wrote above? It works!
Why dont u try the solution I wrote above? It works!
ASKER
I never said it was good, but i just needed to get something out quickly- i see the bad side to this approach, its a shame those people in sun, couldn't write a time out on a thread- don't you think
ASKER
This question has a deletion request Pending
This question no longer is pending deletion
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
hey dont go on giving points without using the class ,it's like getting a free gift ,pls use the class and be benefited !
I do hope that you go on using it !
Thanks
I do hope that you go on using it !
Thanks