Java: Как прервать / остановить поток?

Я пытаюсь остановить поток, но я не могу этого сделать:

public class Middleware {

public void read() {
    try {
        socket = new Socket("192.168.1.8", 2001);

        // code .. 

        Scan scan = new Scan();
        thread = new Thread(scan);
        thread.start();

    } catch (UnknownHostException ex) {
        ex.printStackTrace();

    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

class Scan extends Thread {

    public void run() {

        while (true) {
            try {
            // my code goes here

            } catch (IOException ex) {
                thread.currentThread().interrupt();
            }
        }
    }
}

public void stop() {
    Thread.currentThread().interrupt();
}

// get and setters
}

Поэтому, даже когда я вызываю метод stop, поток не останавливается. Это поддерживает жизнь.

Как я могу прервать / остановить эту тему?

ОБНОВЛЕНИЕ(@ маленький подход)

private void tb_startActionPerformed(java.awt.event.ActionEvent evt) {                                         
    Middleware middleware = new Middleware();

    if (tb_start.getText().equals("Start")){
        tb_start.setText("Stop");

        // starting to read rfid tags
        middleware.read();
    }else{
        tb_start.setText("Start");

        // stop reading rfid tags
        middleware.stop();
    }
}

Класс Middleware:

public class Middleware {

    private Scan scan;

    public void read() {

        scan = new Scan();
        scan.start();
    }

    private class Scan extends Thread {

        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("reading...");
            }
        }
    }

    public void stop() {
        if (scan != null) {
            scan.interrupt();
        }
    }
}

Но когда я пытаюсь остановить поток, это не так. Что может быть не так в коде выше?

С наилучшими пожеланиями, Вальтер Энрике.

8 ответов

Решение

Там действительно нет причин, вам нужно использовать volatile флаг. Вместо этого просто запросите поток для его состояния с isInterrupted(), Кроме того, почему вы оборачиваете Scan объект потока в другом объекте потока? Это кажется совершенно ненужным для меня.

Вот что ты должен делать

public class Middleware {
    private Scan scan;

    public void read() {
        try {
            // do stuff

            scan = new Scan();
            scan.start();
        } catch (UnknownHostException ex) {
            // handle exception
        } catch (IOException ex) {
            // handle exception
        }
    }

    private class Scan extends Thread {

        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    // my code goes here
                } catch (IOException ex) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }

    public void stop() {
        if(scan != null){
            scan.interrupt();
        }
    }
}

Вот пример. Кроме того, я бы не рекомендовал расширять Thread,

Просто return; от вашего времени и поток умрет, не нужно вызывать stop() или interrupt(). Если вы хотите сделать это извне, используйте этот шаблон и вызовите requestStop(),

class Scan extends Thread {
    private volatile stop = false;
    public void run() {

        while (!stop) {
            try {
            // my code goes here

            } catch (IOException ex) {
                stop = true;
            }
        }
    }

    public void requestStop() {
        stop = true;
    }

}

"Много использования stop() должен быть заменен кодом, который просто изменяет некоторую переменную, чтобы указать, что целевой поток должен прекратить работу."- java.lang.Thread

Обычный способ остановить поток - иметь флаг volatile, а затем проверить это в методе run. т.е.

class Scan extends Thread {
    volatile stop = false;
    public void run() {

        while (!stop) {
            try {
            // my code goes here

            } catch (IOException ex) {
                thread.currentThread().interrupt();
            }
        }
    }

    public void stop(){
        stop = true;
    }
}

Вы можете позвонить scan.stop(),

Если вы хотите прервать работающий поток, вам нужен доступ к объекту потока.

thread = new Thread(scan); thread.start(); тогда скажи

thread.interrupt();

это прервет работающий поток.

Полностью согласен с Джимом. Просто добавить. Если ваш поток заблокирован внутри блока try, например, для чтения потока данных и т. Д., То прервите поток или закройте поток. В обоих случаях поток должен быть снова пробужден, и тогда он сможет увидеть изменение значения "stop" boolean и умереть естественным образом, выпадая из метода run. По крайней мере, это то, что я сделал, чтобы убить мои потоки в ветке отключения моего сервера.

Вместо использования Thread.stop() или Thread.interrupt() вы можете использовать внешние блокировки. По сути, когда вы пытаетесь использовать встроенную блокировку, большую часть времени любое прерывание, которое вы выполняете в потоке, неуправляемо.

Блокировка повторного входа предоставляет вам методы, упомянутые ниже.

lock() 
unlock() 
tryLock() 
lockInterruptibly() 
isHeldByCurrentThread() 
getHoldCount() 

Проверьте приведенный ниже пример

final ReentrantLock reentrantLock = new ReentrantLock();    
    @Override
    public void performTask() {
        reentrantLock.lock();
        try { 
             System.out.println(Thread.currentThread().getName() + ": Lock acquired.");
             System.out.println("Processing...");
             Thread.sleep(2000);
        } catch (InterruptedException e) {
             e.printStackTrace();
        } finally {
             System.out.println(Thread.currentThread().getName() + ": Lock released.");
         reentrantLock.unlock();
            }
    }

Это делает ваш код элегантным и лучше обрабатывает прерывания.

    public void run()
    { 
         while (!Thread.currentThread().isInterrupted()) 
         {
        //do something here
        if(condition)
       {
           Thread.currentThread().interrupt();
       }
   }
Другие вопросы по тегам