Stop thread and again start giving IllegalThreadStateException in blackberry

前端 未结 2 1359
轮回少年
轮回少年 2020-12-06 06:10

I am getting IllegalThreadStateException exception when using following code: I have already started this thread once(by using thread.start()) and

2条回答
  •  不知归路
    2020-12-06 06:34

    In addition to Nate's answer.

    AnkitRox states in his comment:

    Thanks Nate. I was also trying your method. But the problem occurred at that time was, it was start a new thread for the new instance and previous thread was also working.

    So it looks like the problem is "the thread is still running even if I called interrupt on it". Consider this sample (it is ugly, but enough to show the main idea):

    final Thread t = new Thread(new Runnable() {
        public void run() {
            while (true) {
                for (int i = 0; i < 100000000; i++); // simulate some action
                System.out.println("hi, interrupted = " 
                        + Thread.currentThread().isInterrupted());
            }
        }
    });
    t.start();
    new Timer(true).schedule(
        new TimerTask() {
            public void run() {
                t.interrupt();
            }
        },
        1000 // 1 second delay
    );
    

    Note, the thread continues to run even after interrupt() has been called. The produced output is:

    hi, interrupted = false
    hi, interrupted = true
    hi, interrupted = true
    hi, interrupted = true
    ...
    hi, interrupted = true
    

    Actually the programm never stops unless closed forcefully. So what then the interrupt() does? It just sets the interrupted flag to true. After interrupt() has been called the Thread.currentThread().isInterrupted() starts to return false. And that's all.

    Another case is if interrupt() is called while the thread is blocked in an invocation of one of the methods that throw InterruptedException, then that method will return throwing the InterruptedException. And if thread's code just "eats" that exception, then the thread will still continue running, consider a sample:

    final Thread t = new Thread(new Runnable() {
        public void run() {
            while (true) {
                System.out.println("hi, interrupted = " 
                        + Thread.currentThread().isInterrupted());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    System.out.println("got InterruptedException");
                }
            }
        }
    });
    t.start();
    new Timer(true).schedule(
        new TimerTask() {
            public void run() {
                t.interrupt();
            }
        },
        1000 // 1 second delay
    );
    

    Note, the thread continues to run even after interrupt() has been called. The produced output is:

    hi, interrupted = false
    got InterruptedException
    hi, interrupted = false
    hi, interrupted = false
    ...
    hi, interrupted = false
    

    Note, this time interrupted = false even after interrupt() has been called. This is because whenever InterruptedException is caught, the interrupted flag is reset to false.

    In Java stopping a thread is cooperative mechanism. Meaning it can not be done without cooperation from the thread itself. Here is the fixed version of the above sample:

    final Thread t = new Thread(new Runnable() {
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("hi, interrupted = " 
                        + Thread.currentThread().isInterrupted());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    System.out.println("we've been interrupted");
                    // restore the interrupted flag
                    Thread.currentThread().interrupt();
                }
            }
        }
    });
    t.start();
    new Timer(true).schedule(
        new TimerTask() {
            public void run() {
                t.interrupt();
            }
        },
        1000 // 1 second delay
    );
    

    So the correct approach should be to periodically check the interrupted flag. And if interrupted status is detected then just return ASAP. Another common option is not to use Thread.interrupt() at all, but some custom boolean instead.

提交回复
热议问题