среда, 1 августа 2012 г.

threads: interrupt

    Демонстрация работы нестатического метода thread.isInterrupted() - читает значение флага прерывания, не очищая его. После того, как флаг прерывания установлен, он остается выставленным неограниченно долго
public class InterruptExample_0_isInterrupted {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                Thread myThread = Thread.currentThread();
                while (true) {
                    System.out.println(myThread.isInterrupted());
                    for (long k = 0; k < 1_000_000_000L; k++) ;
                }
            }
        });
        thread.start();
        Thread.sleep(1000);
        thread.interrupt();
    }
}
>> false
>> false
>> false
>> true
>> true
>> true
>> true
... дальше только true


    Демонстрация работы статического метода Thread.interrupted() - читает значение флага прерывания, очищая его. Т.е. первое же чтение очищает флаг
public class InterruptExample_1_interrupted {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println(Thread.interrupted());
                    for (long k = 0; k < 1_000_000_000L; k++) ;
                }
            }
        });
        thread.start();
        Thread.sleep(1000);
        thread.interrupt();
    }
}
>> false
>> false
>> false
>> true
>> false
>> false
>> false
... дальше только false

    Демонстрация передачи сигнала о прерывании одного потока - другому
public class InterruptExample_2_isInterrupted_while {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                Thread myThread = Thread.currentThread();
                while (!myThread.isInterrupted()) {
                    System.out.println("Hello!");
                    for (long k = 0; k < 1_000_000_000L; k++) ;
                }
            }
        });
        thread.start();
        Thread.sleep(1000);
        thread.interrupt();
    }
}
>> Hello!
>> Hello!
>> Hello!

    Демонстрация передачи сигнала о прерывании одного потока - другому, при этом не только выставляется флаг прерывания (доступный для чтения по isInterrupted()), но и 
1) попытка войти в метод sleep() с выставленным флагом
2) или изменение состояния флага когда метод спит (sleep())
приводит к выбрасыванию InterruptedException
public class InterruptExample_3_sleep_while {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                Thread myThread = Thread.currentThread();
                while (!myThread.isInterrupted()) {
                    System.out.println("Hello!");
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        System.out.println("I interrupted: by exception");
                        return;
                    }
                }
                System.out.println("I interrupted: by flag");
            }
        });
        thread.start();
        Thread.sleep(1000);
        thread.interrupt();
    }
}
>> Hello!
>> Hello!
>> Hello!
>> Hello!
>> Hello!
>> I interrupted: by exception

    wait() ведет себя аналогично sleep()
public class InterruptExample_4_wait_while {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                Object lock = new Object();
                Thread myThread = Thread.currentThread();
                while (!myThread.isInterrupted()) {
                    System.out.println("Hello!");
                    try {
                        synchronized (lock) {
                            lock.wait(200);
                        }
                    } catch (InterruptedException e) {
                        System.out.println("I interrupted: by exception");
                        return;
                    }
                }
                System.out.println("I interrupted: by flag");
            }
        });
        thread.start();
        Thread.sleep(1000);
        thread.interrupt();
    }
}

    Неправильная остановка потока с помощью нереализованного destroy()
public class InterruptExample_5_destroy_while {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("Hello!");
                    for (long k = 0; k < 1_000_000_000L; k++) ;
                }
            }
        });
        thread.start();
        Thread.sleep(1000);
        thread.destroy();
    }
}
>> Hello!
>> Hello!
>> Hello!
>> Exception in thread "main" java.lang.NoSuchMethodError
>> Hello!
>> Hello!
>> Hello!
... дальше "Hello!"

    Неправильная остановка потока с помощью stop()
public class InterruptExample_6_stop_while {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("Hello!");
                    for (long k = 0; k < 1_000_000_000L; k++) ;
                }
            }
        });
        thread.start();
        Thread.sleep(1000);
        thread.stop();
    }
}
>> Hello!
>> Hello!
>> Hello!

    Неправильная приостановка потока с помощью suspend()/resume()
public class InterruptExample_7_suspend_while {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("Hello!");
                    for (long k = 0; k < 1_000_000_000L; k++) ;
                }
            }
        });
        thread.start();
        Thread.sleep(1000);
        thread.suspend();
        Thread.sleep(1000);
        thread.resume();
    }
}

    Классическая статья от Sun, в которой объяснено, почему destroy()/stop()/suspend()/resumr() - это зло = "Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?"