What is the skeleton of your run()?
like:
  public void run() {
    ...
    extern_func1(...);
    ...
  }or:
  public void run() {
    while(true) {
      ...
      extern_func1(...);
      ...
    }
  }

解决方案 »

  1.   

    是这种样子的,没有循环的:  public void run() {
        ...
        extern_func1(...);
        ...
      }extern_func1(...);是一个别人写的关于ftp类的函数,实际使用中发现这个ftp类在连接有问题的ftp服务器时会出现停在某处不再反应的问题,于是我希望从外面强行中断它
      

  2.   

    设置一个private volatile(可能写错了?) boolean cancel = false;run(){
    while(!cancel){
    //do anything u want
    }
    }然后public void cancel(){
    cancel = true;
    }要废掉这个thread,调用cancel就行
      

  3.   

    I really don't know how to stop the thread except the stop(but stop() does not release the resources and unsafe). I don't think jigsaw's idea will work because the program has no chance to check the while(!cancel) when it's executing or stuck in the "//do anything u wnat".
      

  4.   

    我想对jigsaw(jigsaw)的方法作点补充,再做一个线程,作为系统的主线程,监控包括你说的要运行的ftp线程,当满足一定条件时,更改while(!cancel)中的cancel,可以退出线程,这也是sun推荐的方法。详细请:http://java.sun.com/products/jdk/1.2/docs/guide/misc/threadPrimitiveDeprecation.html
    其中倒数第3问,比较适合。
      

  5.   

    helpall() 你确定我的方法不可以?你尝试一下把注意 cancel被声明为volatile
      

  6.   

    另外,如果把这个县城宣布为null很容易导致deadlock
      

  7.   

    jigsaw(jigsaw): 
    问题正如helpall()说的那样,程序会在run()中一个函数上停住,而不会再运行到while(!cancel)处。另外:volatile是什么啊?麻烦解释一下。
      

  8.   

    to jigsaw(jigsaw): 
    Here's a little test program to facilitate your testing. If you really can work it out, I will create a new posting to score you 200 points. I am serious.
    class ThreadTest extends Thread {
            public volatile boolean  isCancel = false;        public static void main(String[] args) {
                    ThreadTest t = new ThreadTest();
                    t.start();
                    wait(10);
                    t.isCancel = true;
                    System.out.println("\nMain ends.");
                    wait(10);
            }        public void run() {
                    while(!isCancel) {
                            System.out.println("Enter endless loop");
                            for(int i = 0;i < 300 ; i++) {
                                    wait(1);
                                    System.out.print(i+" ");
                            }
                    }
                    System.out.println("End endless loop");
            }        public static void wait(int second) {
                    try{
                            Thread.sleep(second * 1000);
                    }catch(Exception e){}
            }
    }
      

  9.   

    to helpall:I'm sorry I was totally wrong.
    However, I've figured out how to abort or cancel a living thread.
    Hope this time I didnt make any mistakes.
    Any suggestion will be highly appreciated./*******************Poster starts here****************************/
    public class Poster implements Runnable {    private String query = null;
        private volatile boolean aborting = false;
        private boolean isCanceled = false;    Poster() {
            Thread t = new Thread(this);
            t.start();
        }    public synchronized void sendPost(String query) {
            this.query = query;
            notify();
        }    public void run() {
            running:
            while (!aborting) {
                String query;
                synchronized (this) {
                    System.out.println("I'm still eligible to doSend");
                    while (this.query == null) {
                        try {
                            wait();
                        } catch (InterruptedException e) {
                        }
                        if (aborting) {
                            System.out.println("being aborted");
                            break running;
                        }
                    }
                    query = this.query;
                    this.query = null;
                }
                //must have been notified by sendPost
                doSend(query);
            }
            System.out.println("I'm useless");
        }    /*
        *surppose we need do send step by step, either step is 
        *time consuming
        *the 1st step will costs 3 sec(without being canceled), 
        *and the 2nd step
        *will never end untill being canceled.
        */
        private void doSend(String query) {
            int i = 0;
            for (; !isCanceled && i < 3; i++) {
                System.out.println(query + " stepI " + i);
                try {
                    Thread.sleep(1 * 1000);
                } catch (InterruptedException e) {
                }
            }
            for (; !isCanceled; i++) {
                System.out.println(query + " stepII " + i);
                try {
                    Thread.sleep(1 * 1000);
                } catch (InterruptedException e) {
                }
            }
        }   /*
       *This is just for tidying up - the instance is useless 
       *after it has
       *been called
       */
        public void abort() {
            aborting = true;
            synchronized (this) {
                notify(); // wake up our posting thread and kill it
            }
        }    public synchronized void cancel() {
            System.out.println("I'm being canceled, however, I'll be back soon");
            isCanceled = true;
        }    public synchronized void resume() {
            System.out.println("I'm back as I've told you");
            isCanceled = false;
        }
    }
    /**********************Poster ends here*****************//****************ThreadTest starts here**********/
    public class ThreadTest {
        private static Poster poster = new Poster();    public static void main(String[] args) {
            poster.sendPost("test");
            wait(2);
            poster.cancel();
            wait(5);
            poster.resume();//although having been cancled, the thread is not "dead"
            poster.sendPost("test2");
            wait(5);
            poster.cancel();//the point is: before aborting, u must cancel it first
            poster.abort();//now the thread is useless
            poster.sendPost("test3"); //this will never work
        }    public static void wait(int second) {
            try {
                Thread.sleep(second * 1000);
            } catch (InterruptedException e) {
            }
        }
    }/****************ThreadTest ends here**********/
    /**********************************************/thank you for your testingBest Regards,
    jigsaw
      

  10.   

    to jigsaw:
       这一段程序应该没有问题,但还是没有能解决顶楼的问题啊。 你把isCanceled放到doSend中,而bbdolly没有你这么幸运啊。看来我还不能给你分,顶楼看着办吧。 :-)
      

  11.   

    what's more:If the core method doSend() doesnt check isCancled on each step, there's no way out, since I cant find any solution to break from a endless loop without watching on a certain flag.
    Only on condition that doSend() will never end, do we have to call cancel() before abort(). Otherwise, if we can assure that doSend() is able to finish its work and give us a response, we have a choice to wait till it ends and then abort it. Thus, it's optional with us to call cancel() or not.to bbdolly:Only variables may be volatile ; declaring them so indicates
    that such variables might be modified asynchronously, so the compiler takes special precautions.  --copied from sybex
      

  12.   

    可以用interrupted()方法代替stop()呀!
      

  13.   

    看了前面的讨论,我觉得可以结合的来使用。
    首先,肯定要有一个监视线程。如果,搂主连这个要求都无法满足,那就没戏了。
    其次,设置一个volatile的flag。
    再次,监视线程要保留该工作线程的一个reference(否则怎么监呀?)。具体的机制:
    当监视线程觉得可以干掉这个工作线程的时候,造一个InterruptException,终止正在运行的工作线程,这样就可以避免以下的情况:
    (以下是引用前面的话)
    jigsaw(jigsaw): 
    问题正如helpall()说的那样,程序会在run()中一个函数上停住,而不会再运行到while(!cancel)处。这样不管是什么操作extern_func1(...)(这是搂主用来封装ftp函数的method),都会被迫终止。而去检查 stopRequested 这个flag了。然后,上面的兄弟都说了,我就不重复了。下面是我的例子:
    public class KillMeSoftly extends Object implements Runnable {       private volatile boolean stopRequested;      private Thread runThread;      public void run() {         runThread = Thread.currentThread();          stopRequested = false;          int count = 0;          while ( !stopRequested ) {             System.out.println("Running ... count=" + count);              count++;             try {                  Thread.sleep(300);               } catch ( InterruptedException x ) {                 System.out.println("Caught a InteruptedException! It is time to check the stopRequested!");
                     Thread.currentThread().interrupt(); // reassert              }          }      }      public void stopRequest() {          stopRequested = true;          if ( runThread != null ) {               runThread.interrupt();         }      }      public static void main(String[] args) {          AlternateStop as = new AlternateStop();           Thread t = new Thread(as);           t.start();          try {             Thread.sleep(2000);          } catch ( InterruptedException x ) {              // ignore           }
              as.stopRequest();       }   }在此郑重声明:此例子引用自
    《Java Thread Programming》  
    Paul Hyde 
    Copyright &copy; 1999 Sams Publishing 
    吐血推荐的好书呀!如果搂主的ftp函数牵涉到I/O操作,那么上面的方法还是不行的。你就再开一个贴子问我吧! 
      

  14.   

    谢谢大家如此热心的帮助! :)看来……基本上……这个问题……暂时是没有办法解决的。不知道这种从外界停止一个线程是否在原理上就存在不可避免的安全隐患,还是sun公司发现从前写的stop()有问题但bug太深短时间无力补救只能很遗憾的建议大家从线程内部配合实现这个功能。我是在做一个扫描ftp服务器上文件的程序遇到这个问题的。用的是NetComponents 中的com.oroinc.net.ftp这个类,这个东西在connect()某些有问题的ftp服务器时会死在这个函数,于是我做了个监视线程,发现这个线程一段时间没有动作后就kill掉它……用interrupt(),然后置null不知道会不会有什么资源得不到释放的问题,由于这个程序基本上是不停的反复扫描,如果存在资源不能完全释放,会有一些隐患。
      

  15.   

    Norwaywoods可以共享一下那本书吗?谢谢!