我正在尝试为另一个类中的特定任务创建一个线程。线程正在启动任务,但是当我尝试停止线程时,它没有停止。线程一直持续到循环。你能帮帮我吗?
线程类:
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();
}
}
}
}
答案 0 :(得分:7)
您的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() {
for(int t=0;t<100;t++) {
try {
System.out.println(dispMsg + t);
Thread.sleep(1000);
} catch (InterruptedException e) {
// re-interrupt the thread and stop looping
Thread.currentThread().interrupt();
return;
}
}
}
答案 1 :(得分:1)
当您捕获InterruptedException
类中的DisplayMsg
时,将重置中断的标志。
捕获异常很好,但是如果你需要随后知道线程是否被中断,你需要通过在catch块中再次中断Thread.currentThread.interrupt();
来重置标志并打开循环/返回。
答案 2 :(得分:1)
更简单的设计可实现您的需求如下:
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);
}
}
}
这只会让InterruptedException
传播并结束MyThread
,而不需要自己动手。
答案 3 :(得分:0)
我相信发生的事情是你需要在每次睡眠前检查Thread.currentThread()。isInterrupted()。你在方法中调用show()只会迭代100秒然后你的while循环会检查线程是否被中断。将您的支票移动到您的show方法,看它是否看到中断的旗帜。根据下一个答案,您还应该在捕获InterruptedException时设置Thread中断标志。