Java中线程的正确方法
我开始学习Java中的线程,现在我有点困惑。 我希望这是一个合适的地方。 我做了一个测试的小程序:Java中线程的正确方法,java,multithreading,Java,Multithreading,我开始学习Java中的线程,现在我有点困惑。 我希望这是一个合适的地方。 我做了一个测试的小程序: public class GetInfo implements Runnable { //private static boolean stopPointerInfo = false; private static Thread tn; public static void StartPointerInfo() { //stopPointerI
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()
方法,还是像注释中那样使用布尔变量
使用这种方法,我不能使用中断
,我必须使用布尔版本,因为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();
}
}
布尔标志解决方案是脆弱的,因为它不能保证更新在不同线程之间可见。要解决此问题,可以将其声明为volatile,但如果设置布尔标志,则不会像在第一个版本中那样中断
sleep
调用。因此,首选使用中断
我认为没有理由将线程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();
Thread.currentThread().isInterrupted();
您不需要使用
静态线程
在run()
方法中,需要测试当前线程是否已中断。您不需要访问tn
。您可以这样做:
GetInfo infoWorker = GetInfo.StartPointerInfo();
...
infoWorker.StopPointerInfo();
Thread.currentThread().isInterrupted();
或
(请注意,这两个的行为是不同的。一个清除中断标志,另一个不清除。)
或者,您可以将static
字段更改为实例字段,并使所有GetInfo
方法成为实例方法。这意味着您可以实例化GetInfo
的多个实例,每个实例都创建自己的线程
,并将引用保存在实例字段中
还有两点:
- 创建和处理线程的方式效率很低。(启动一个线程是昂贵的。)更好的方法是重新构造代码,以便它可以使用一个线程
- 调用方法
和StartPointerInfo
是不好的风格。Java方法名称应始终以小写字母开头StopPointerInfo