我开始学习Java中的线程,现在我有点困惑。 我希望这是一个正确的问题。 我制作了一个小程序进行测试:
public class GetInfo implements Runnable {
//private static boolean stopPointerInfo = false;
private static Thread tn;
public static void StartPointerInfo() {
//stopPointerInfo = false;
tn = new Thread(new GetInfo());
tn.start();
System.out.println("After start1");
}
public static void StopPointerInfo() {
//stopPointerInfo = true;
tn.interrupt();
}
@Override
public void run() {
// while (stopPointerInfo == false) {
while (! tn.isInterrupted() ) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
tn.interrupt();
}
.
.
doSomething
}
}
}
因为run()
方法必须知道哪个线程被中断,所以我必须使用线程tn
的全局定义?
我应该像我一样使用interrupt()
方法,还是应该像评论一样使用布尔变量?
使用此方法,我无法使用interrupt
,我必须使用布尔版本,因为Runnable r
不知道此处的线程吗?
public class GetInfo {
private static boolean stopPointerInfo = false;
public static void StartPointerInfo() {
stopPointerInfo = false;
getPointerInfo();
}
public static void StopPointerInfo() {
stopPointerInfo = true;
}
public static void getPointerInfo() {
Runnable r = new Runnable() {
@Override
public void run() {
while (stopPointerInfo == false) {
try {
Thread.sleep(500);
} catch (InterruptedException e) { }
.
.
doSomething
}
}
};
new Thread(r).start();
}
}
答案 0 :(得分:0)
布尔标志解决方案很脆弱,因为无法保证不同线程之间可以看到更新。要解决此问题,您可以将其声明为volatile,但如果设置布尔标志,则不要像第一个版本那样中断sleep
调用。因此,首选使用中断。
我认为没有理由将Thread tn
声明为静态。你可以使用:
public class GetInfo implements Runnable {
private final Thread tn;
private GetInfo() {
this.tn = new Thread(this);
this.tn.start();
}
public static GetInfo StartPointerInfo() {
GetInfo info = new GetInfo();
System.out.println("After start1");
return info;
}
public void StopPointerInfo() {
tn.interrupt();
}
...
}
并像这样使用它:
GetInfo infoWorker = GetInfo.StartPointerInfo();
...
infoWorker.StopPointerInfo();
答案 1 :(得分:0)
您无需使用static Thread
。
在run()
方法中,您需要测试当前线程是否已被中断。您无需访问tn
。你可以这样做:
Thread.currentThread().isInterrupted();
或
Thread.interrupted();
(注意这两者的行为是不同的。一个清除中断标志而另一个不清除。)
或者,您可以将static
字段更改为实例字段,并创建所有GetInfo
方法实例方法。这意味着您可以实例化GetInfo
的多个实例,每个实例都创建自己的Thread
并在实例字段中保存引用。
还有两点:
您创建然后处理线程的方式效率很低。 (启动一个线程很昂贵。)更好的方法是重构代码,以便它可以使用thread pool。
调用您的方法StartPointerInfo
和StopPointerInfo
是不好的。 Java方法名称应始终以小写字母开头。