为什么我的线程无法停止???
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的任何数字)时,线程无法停止?请帮我解决这个问题...感谢任何帮助。
答案 0 :(得分:3)
因为此代码不在线程的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;
}
}
}
答案 1 :(得分:0)
我确定你是否多次运行该程序,当程序实际停止时会出现这种情况。
原因是当你运行程序时,执行
的可能性要大得多if(rp.num == 1) {rp.stop();}
num++
方法run()
之前的更改值。
但是,您可能会遇到一种情况,即run方法中的循环在main方法中的if语句之前执行。
确保这种情况发生的一种方法是不断检查条件:
e.g。
public static void main(String[] a) {
runP rp = new Threadz().new runP();
while(true){
if(rp.num == 1) {
rp.stop();
break;
}
}
}
答案 2 :(得分:0)
下面的语句是在线程开始执行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进行测试。
答案 3 :(得分:0)
检查public ActionResult GetData([DataSourceRequest]DataSourceRequest request)
{
IQueryable<CarModel> entity = getCars().ProjectTo<CarModel>();
var response = entity.ToDataSourceResult(request);
return Json(response,JsonRequestBehavior.AllowGet);
}
必须恰好发生在rp.num == 1
正是一个点的位置,这是不太可能的。
在rp.num
方法中,启动一个每200毫秒递增main
的线程。然后,检查是否num
,但是当执行此代码时,取决于您无法真正控制的许多因素(操作系统的安排等等)。这可能是在10 ms之后(其中值为1),但也可能在300 ms之后(当值已经为2时)。当线程准确启动时也不确定。因此,您的线程也可能仅在测试后启动。您可以使用简单的打印语句num == 1
替换支票if(rp.num == 1) {rp.stop()};
,轻松地对此进行测试。如果你在打印之前再等一段时间,你可能会对我正在谈论的内容有更好的感受。
假设你想要从外面阻止可运行,我建议使用像Observer pattern这样的东西:
System.out.println(rp.num)
并且您的主要方法看起来像
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();
}
}