Java 线程无法停止
为什么我的线程不能停止Java 线程无法停止,java,multithreading,Java,Multithreading,为什么我的线程不能停止 class Threadz { class runP implements Runnable { int num; private volatile boolean exit = false; Thread t; public runP() { t = new Thread(this, "T1"); t.start(); }
class Threadz {
class runP implements Runnable {
int num;
private volatile boolean exit = false;
Thread t;
public runP() {
t = new Thread(this, "T1");
t.start();
}
@Override
public void run() {
while(!exit) {
System.out.println(t.currentThread().getName()+": "+num);
num++;
try {
t.sleep(200);
} catch(InterruptedException e) {}
}
}
public void stop() {
exit = true;
}
}
public static void main(String[] a) {
runP rp = new Threadz().new runP();
if(rp.num == 1) {rp.stop();}
}
}
如果我使用rp.num==0,线程可以立即停止。但是,为什么当我更改rp.num==x(x是任何大于0的数字)时线程不能停止?请帮我解决这件事。。。感谢您的帮助。因为此代码不是在线程的run()方法中执行的:
runP rp = new Threadz().new runP();
if (rp.num == 1) {
rp.stop();
}
它与0一起工作,因为int的默认值为0。
但这并不一定在应用程序的所有执行中都是正确的,因为runP
的线程可以在检查之前运行并递增num
:if(rp.num==0)
在runP线程的run方法中移动停止条件:
@Override
public void run() {
while(!exit) {
System.out.println(t.currentThread().getName()+": "+num);
num++;
try {
t.sleep(200);
} catch(InterruptedException e) {}
if (rp.num == 1) {
exit = true;
}
}
}
我敢肯定,如果你多次运行这个程序,当程序真正停止运行时,就会出现这种情况 原因是在运行程序时,执行的机会要大得多
if(rp.num == 1) {rp.stop();}
在run()
方法中的num++
之前更改值
然而,您可能会偶然遇到这样一种情况,即在主方法中的if语句之前执行run方法中的循环
确保发生这种情况的一种方法是持续检查以下情况:
e、 g
在线程开始执行run方法之前执行下面的语句
if(rp.num == 1) {rp.stop();}
在上述语句之前添加Thread.sleep,它可以正常工作,因为它将在启动循环后执行此语句
public static void main(String[] a) {
runP rp = new Threadz().new runP();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(rp.num > 1) {rp.stop();}
}
我已经将它设置为>1进行测试。检查
rp.num==1
必须恰好发生在rp.num
正好为1的点上,这是不太可能的
在main
方法中,您启动一个线程,该线程每200毫秒递增num
。之后,您将检查num==1
,但此代码的确切执行时间取决于许多您无法真正控制的因素(操作系统的调度等)。这可能在10毫秒之后(值为1),但也可能在300毫秒之后(值已经为2)。另外,线程何时准确启动也不确定。因此,您的线程也可能仅在测试之后启动。通过替换checkif(rp.num==1){rp.stop()代码>使用简单的打印语句System.out.println(rp.num)
。如果您在打印之前再等待一段时间,您可能会更好地了解我所说的内容
假设您想阻止来自外部的runnable,我建议使用以下方法:
你的主要方法是
public static void main(String[] args) {
MyListener l = new MyListener(1);
Runnable r = new MyRunnable(l);
new Thread(r).start();
}
我猜runP rp=newthreadz().newrunp()代码>正在创建和启动线程。但是,如果(rp.num==1){rp.stop();}
恰好在该线程之后执行,则可能正好在另一个线程实际开始运行之前执行,因此num
仍然为0。此外,线程可能已经运行多次,因此检查<代码> rpn==1 非常脆弱,并且可能更经常失败。请考虑使用<代码> RPNUM > 1 < /COD>而不是<代码> RPNU==1 < /COD>停止您的线程以确保您不会意外跳过停止条件。AtomicBoolean能够真正保持这种方法。此外,您需要在两个线程之间有一个完美的计时来命中==。你最好选择>好的。。我尽了最大努力,但最终还是做出了这个选择。。。谢谢brobtw如果我有两个线程,如何将var从一个线程传递到另一个线程?你能告诉我怎么做吗?不客气:)不需要传递变量,只需要在线程之间共享它。您可以使用在runP线程之间共享的AtomicInteger,并在runP的构造函数中提供AtomicInteger。应该很好,是的。我刚刚注意到,对于多线程处理,100次重复中有99次。所以我只是简单地将标签添加到搜索中,然后仔细决定是否有值得投票的答案;-)空缺已经结束,你又回来了。很高兴看到你回来:)那么放松了吗?谢谢这个标签:)我会检查你的。也许可以做点好生意:)
class MyRunnable implements Runnable {
private final MyListener l;
private volatile boolean exit;
int num;
public MyRunnable(MyListener l) {
this.l = l;
exit = false;
}
@Override
public void run() {
while(!exit) {
System.out.println(t.currentThread().getName()+": "+num);
l.check(num++);
try {
t.sleep(200);
} catch(InterruptedException e) {}
}
}
public void stop() {
exit = true;
}
}
class MyListener {
private final threshold;
public MyListener(int x) {
this.threshold = x;
}
public void check(MyRunnable r, int num) {
if (num >= threshold)
r.stop();
}
}
public static void main(String[] args) {
MyListener l = new MyListener(1);
Runnable r = new MyRunnable(l);
new Thread(r).start();
}