我试图阻止一个帖子,但我不能这样做:
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。
答案 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();
}
}
这使您的代码更优雅,并以更好的方式处理中断。