无法停止Java线程

无法停止Java线程,java,multithreading,Java,Multithreading,我正在尝试为特定任务创建一个线程,以便在另一个类中运行。线程正在启动任务,但当我尝试停止线程时,它没有停止。线程一直持续到循环结束。你能帮帮我吗 螺纹等级: package com.development; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing

我正在尝试为特定任务创建一个线程,以便在另一个类中运行。线程正在启动任务,但当我尝试停止线程时,它没有停止。线程一直持续到循环结束。你能帮帮我吗

螺纹等级:

package com.development;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ThreadExample extends JFrame {
    MyThread mt;
    Thread th;
    ThreadExample(){        
        JPanel p1 = new JPanel();
        p1.setPreferredSize(new Dimension(400,400));
        JButton b1 = new JButton("Start");
        JButton b2 = new JButton("Stop");
        b1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                  mt = new MyThread();
                  th = new Thread(mt);
                 th.start();
            }
        });
        b2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                th.interrupt();               
            }
        });
        p1.add(b1);
        p1.add(b2);
        this.getContentPane().add(p1);
        this.pack();
        this.setVisible(true);
    }
    public static void main(String arg[]) {
        ThreadExample mt = new ThreadExample();
        mt.setVisible(true);
    }
    public class MyThread implements Runnable{
        private volatile boolean runnable=true;
        DisplayMsg dm = new DisplayMsg("Cycle");
        @Override
        public void run() {
            while(!Thread.currentThread().isInterrupted()) {
            // TODO Auto-generated method stub
               dm.show();                 
            }    
        }
    }    
}


DisplayMsg class:

package com.development;

public class DisplayMsg {
    private String dispMsg; 
    private boolean runnable;
    DisplayMsg(String dispMsg){
        this.dispMsg=dispMsg;
    }
    public void show() {
        for(int t=0;t<100;t++) {        
        try {
            System.out.println(dispMsg + t);
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }
    }   
}
package.com.development;
导入java.awt.Dimension;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类ThreadExample扩展了JFrame{
神话阅读;
螺纹th;
ThreadExample(){
JPanel p1=新的JPanel();
p1.设置首选尺寸(新尺寸(400400));
JButton b1=新JButton(“开始”);
JButton b2=新JButton(“停止”);
b1.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件arg0){
mt=新的MyThread();
th=新螺纹(mt);
th.start();
}
});
b2.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
th.中断();
}
});
p1.添加(b1);
p1.添加(b2);
this.getContentPane().add(p1);
这个包();
此.setVisible(true);
}
公共静态void main(字符串arg[]){
ThreadExample mt=新的ThreadExample();
mt.setVisible(真实);
}
公共类MyThread实现可运行{
private volatile boolean runnable=true;
DisplayMsg dm=新的DisplayMsg(“循环”);
@凌驾
公开募捐{
而(!Thread.currentThread().isInterrupted()){
//TODO自动生成的方法存根
dm.show();
}    
}
}    
}
DisplayMsg类:
包com.development;
公共类displaymg{
私有字符串dispMsg;
私有布尔可运行;
DisplayMsg(字符串dispMsg){
this.dispMsg=dispMsg;
}
公开展览({

对于(int t=0;t您的DisplayMsg类循环100秒,并忽略中断。事实上,当
Thread.sleep()
被中断时,它会重置中断状态,然后抛出一个InterruptedException。由于您忽略了InterruptedException,线程将继续运行,就好像什么都没有发生一样

public void show() {
    for(int t=0;t<100;t++) {        
        try {
            System.out.println(dispMsg + t);
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
public void show(){

对于(int t=0;t您的DisplayMsg类循环100秒,并忽略中断。事实上,当
Thread.sleep()
被中断时,它会重置中断状态,然后抛出一个InterruptedException。由于您忽略了InterruptedException,线程将继续运行,就好像什么都没有发生一样

public void show() {
    for(int t=0;t<100;t++) {        
        try {
            System.out.println(dispMsg + t);
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
public void show(){

对于(int t=0;t当您在
DisplayMsg
类中捕捉到
InterruptedException
时,中断标志被重置


捕获异常是可以的,但是如果您随后需要知道线程是否已被中断,则需要通过使用
thread.currentThread.interrupt()再次中断来重置标志
在该catch块中,并中断循环/返回。

当您在
DisplayMsg
类中捕获
interruptedeexception
时,interrupted标志被重置


捕获异常是可以的,但是如果您随后需要知道线程是否已被中断,则需要通过使用
thread.currentThread.interrupt()再次中断来重置标志
在该catch块中,并中断循环/返回。

我相信发生的事情是您需要在每次睡眠之前检查!Thread.currentThread().isInterrupted()。您正在调用show()在将迭代100秒的方法中,while循环将检查线程是否被中断。将interrupted检查移动到show方法,看看它是否看到中断标志。根据下面的答案,在捕获InterruptedException时,您还应设置thread interrupted标志。

我相信正在发生的是,您需要在每次睡眠之前检查!Thread.currentThread().isInterrupted()。您正在调用show()在将迭代100秒的方法中,while循环将检查线程是否被中断。将interrupted检查移到show方法,看看它是否看到中断标志。根据下面的回答,在捕获InterruptedException时,还应设置thread interrupted标志。

实现您所需功能的MPER设计如下:

public class MyThread implements Runnable{
    DisplayMsg dm = new DisplayMsg("Cycle");
    @Override public void run() {
        try { while(true) dm.show(); } 
        catch (InterruptedException e) { }
    }
}    

public class DisplayMsg {
  ...
  public void show() throws InterruptedException {
    for(int t=0;t<100;t++) {        
      System.out.println(dispMsg + t);
      Thread.sleep(1000);
    }
}   
公共类MyThread实现可运行{
DisplayMsg dm=新的DisplayMsg(“循环”);
@重写公共无效运行(){
请尝试{while(true)dm.show();}
捕获(中断异常e){}
}
}    
公共类displaymg{
...
public void show()引发InterruptedException{

对于(int t=0;t而言,实现您所需的更简单的设计如下:

public class MyThread implements Runnable{
    DisplayMsg dm = new DisplayMsg("Cycle");
    @Override public void run() {
        try { while(true) dm.show(); } 
        catch (InterruptedException e) { }
    }
}    

public class DisplayMsg {
  ...
  public void show() throws InterruptedException {
    for(int t=0;t<100;t++) {        
      System.out.println(dispMsg + t);
      Thread.sleep(1000);
    }
}   
公共类MyThread实现可运行{
DisplayMsg dm=新的DisplayMsg(“循环”);
@重写公共无效运行(){
请尝试{while(true)dm.show();}
捕获(中断异常e){}
}
}    
公共类displaymg{
...
public void show()引发InterruptedException{

对于(int t=0;是不是下选投票人还在附近,请他解释下选投票?下选投票人还在附近,请他解释下选投票吗?真的很有效。我现在理解这个概念,非常感谢。它真的有效。我现在理解这个概念,非常感谢。不,这不是必需的。
Thread.interrupt
设置被中断的flag、 这是一个持续的更改。
Thread.sleep
所做的第一件事是检查标志,然后才将线程置于等待状态。@MarkoTopolnik抱歉,早上编辑/添加错误。在添加关于的最后一部分后,我在捕获中添加了中断/返回