Java:如何中断/停止线程?

时间:2011-07-06 15:41:45

标签: 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
}

所以,即使我调用方法'停止',线程也不会停止。 它保持活力。

如何中断/停止此线程?

更新 (@little方法)

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();
    }
}

中间件类:

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();
        }
    }
}

但是当我试图阻止线程时,它没有。 上面的代码可能有什么问题?

祝你好运, Valter Henrique。

8 个答案:

答案 0 :(得分:20)

你真的没有理由需要使用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();
        }
    }
}

这是一个example。另外,我不建议延长Thread

答案 1 :(得分:10)

只需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;
    }

}

答案 2 :(得分:5)

stop()的许多用法应该被代码修改,该代码只是修改某个变量以指示目标线程应该停止运行。” - java.lang.Thread

答案 3 :(得分:5)

如果要中断正在运行的线程,则需要访问该线程对象。

thread = new Thread(scan); thread.start(); 然后说

thread.interrupt();

这将中断正在运行的线程。

答案 4 :(得分:4)

停止线程的常用方法是使用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()

答案 5 :(得分:1)

完全同意Jim ..只是添加如果您的线程在try块中被阻止 例如,读取数据流等,然后中断线程或关闭 流。在这两种情况下,线程应该再次被唤醒,然后它将能够看到“stop”布尔值的变化并且通过掉出run方法自然死亡。至少这是我在服务器的关闭线程中杀死我的线程所做的。

答案 6 :(得分:0)

    public void run()
    { 
         while (!Thread.currentThread().isInterrupted()) 
         {
        //do something here
        if(condition)
       {
           Thread.currentThread().interrupt();
       }
   }

答案 7 :(得分:0)

不是使用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();
            }
    }

这使您的代码更优雅,并以更好的方式处理中断。