Link to home
Start Free TrialLog in
Avatar of plaskowj
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?
Avatar of rainmal
rainmal

Could you post ur code.
 
Avatar of plaskowj

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("recursive"):
}

}
>>>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.
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
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("InterruptedException");
    }
    System.out.println("Exiting run()");
  }
}

public class Interrupt extends Applet {
  private Button
    interrupt = new Button("Interrupt");
  private Blocked blocked = new Blocked();
  public void init() {
    add(interrupt);
    interrupt.addActionListener(
      new ActionListener() {
        public
        void actionPerformed(ActionEvent 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.
note ur example of showing system.out.println("recursive"):
is not true in most cases ,in the real world the situation is more like wait() as outlined above.
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,AsyncInputStream.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 IllegalMonitorStateException("current 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 IllegalMonitorStateException("current 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 IllegalMonitorStateException("current thread not owner");
            }
            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 .....
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.

>>>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
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"??
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(AsyncReadBuffer a, Socket s,int t,boolean isReadLine)throws Exception
    {
            this.aReader=a;
        this.sock=s;
            this.isReadLineMode=isReadLine;
            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.getInputStream()));
                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.buff=null;
                                this.sock.close();this.sock=null;
                            }
                            catch (Exception e)
                            {}
                        }
                    }
                }
            }
            catch(Throwable t)
            {
                  System.out.println("Caught Exception during run() in timeout main thread");
                  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
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.getInputStream()));
      
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?
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?
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!
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
This question has a deletion request Pending
This question no longer is pending deletion
ASKER CERTIFIED SOLUTION
Avatar of mbormann
mbormann

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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