Java 线程:如何从线程外部中断线程

Java 线程:如何从线程外部中断线程,java,multithreading,thread-safety,interrupt,Java,Multithreading,Thread Safety,Interrupt,我有一个简单的GUI,其中有两个按钮:Print和Stop 当用户按下“打印”按钮时,已保存的号码将以循环方式连续打印 当用户按下Stop时,打印停止 我在一个单独的线程中处理数字的打印,因为我需要线程在再次打印之前休眠一毫秒 printbn.addActionListener(新ActionListener(){ 已执行的公共无效操作(操作事件arg0){ 线程a=新线程(新可运行(){ 公开募捐{ textArea.setText(“”); 对于(int i=0;i如果您的第一个线程不包含线

我有一个简单的GUI,其中有两个按钮:
Print
Stop

当用户按下“打印”按钮时,已保存的号码将以循环方式连续打印

当用户按下
Stop
时,打印停止

我在一个单独的线程中处理数字的打印,因为我需要线程在再次打印之前休眠一毫秒

printbn.addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件arg0){
线程a=新线程(新可运行(){
公开募捐{
textArea.setText(“”);

对于(int i=0;i如果您的第一个线程不包含线程阻塞操作,您可以检查
for
-循环中的标志,当您按下“停止”按钮时,该标志将设置为
true

公共类WriterThread实现可运行{
private volatile boolean stopped=false;
公共同步无效停止(){
this.stopped=true;
}
公开募捐{
textArea.setText(“”);

对于(int i=0;i如果您的第一个线程不包含线程阻塞操作,您可以检查
for
-循环中的标志,当您按下“停止”按钮时,该标志将设置为
true

公共类WriterThread实现可运行{
private volatile boolean stopped=false;
公共同步无效停止(){
this.stopped=true;
}
公开募捐{
textArea.setText(“”);

对于(inti=0;i使用
AtomicBoolean
作为标志。它将确保线程安全

Runnable r= new Runnable(){

    private AtomicBoolean stop= new AtomicBoolean(false);

    public void run(){
        for(...){

           if(stop.get()){
               break; // break the loop
           }

           ...

        }
    }

    public stop(){
        stop.set(true);
    }
}

Thread a= new Thread(r);
a.start();
r.stop();

使用
AtomicBoolean
作为标志。它将确保线程安全

Runnable r= new Runnable(){

    private AtomicBoolean stop= new AtomicBoolean(false);

    public void run(){
        for(...){

           if(stop.get()){
               break; // break the loop
           }

           ...

        }
    }

    public stop(){
        stop.set(true);
    }
}

Thread a= new Thread(r);
a.start();
r.stop();
final Thread a=新线程(new Runnable()){
公开募捐{
试一试{
textArea.setText(“”);
对于(int i=0;i
final Thread a=new Thread(new Runnable()){
公开募捐{
试一试{
textArea.setText(“”);

对于(int i=0;i为什么来自另一个线程?使用
计时器
或者更好的是使用
ScheduledExtructorService
。在
计时器上调用
取消()
取消()
scheduledfuutre
上。除非您知道自己在做什么并且有充分的理由这样做,否则不要使用原始
线程。@ZerO因为此线程只包含此线程的run方法中的内容。这是一个完全不同的按钮,具有不同的操作侦听器。我可以实现该线程的操作侦听器吗在这个线程内部?我是否遗漏了什么?我不确定我是否搞错了。为什么不将线程声明为全局线程。然后在第二个操作侦听器中调用线程的名称。中断();为什么从另一个线程?使用
计时器
或者更好的方法是使用
ScheduledExtructorService
。调用
取消()
计时器上的
取消()
scheduledfuutre
上。除非您知道自己在做什么并且有充分的理由这样做,否则不要使用原始
线程。@ZerO因为此线程只包含此线程的run方法中的内容。这是一个完全不同的按钮,具有不同的操作侦听器。我可以实现该线程的操作侦听器吗在这个线程内部?我是否遗漏了什么?我不确定我是否弄错了。为什么不将线程声明为全局线程。然后在第二个操作侦听器中调用线程的名称。interrupt()。
stopped
应该声明为
volatile
。如果不是,JIT将对
if
语句进行概率优化(去掉)。对,我弄混了。
stopped
应该声明为
volatile
。如果不是,JIT将按比例优化
If
语句(去掉)。对,我弄混了。
Runnable r= new Runnable(){

    private AtomicBoolean stop= new AtomicBoolean(false);

    public void run(){
        for(...){

           if(stop.get()){
               break; // break the loop
           }

           ...

        }
    }

    public stop(){
        stop.set(true);
    }
}

Thread a= new Thread(r);
a.start();
r.stop();
final Thread a= new Thread(new Runnable(){
    public void run(){
        try {
            textArea.setText("");
            for (int i=0; i<10; i++){
                int result= 0;
                System.out.println(result+"\n"); 
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            // ignore
        } 
    }
});

printBtn.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {

        a.start();
    }
});

stopBtn.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {

       if( a.isAlive() ) {   
           a.interrupt();
       }
    }
});