[英]Correct Way for Threads in Java
我開始學習 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();
}
}
布爾標志解決方案是脆弱的,因為它不能保證更新在不同線程中可見。 為了解決這個問題,你可以將它聲明為 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();
您不需要使用static Thread
。
在run()
方法中,您需要測試當前線程是否已被中斷。 您不需要為此訪問tn
。 你可以這樣做:
Thread.currentThread().isInterrupted();
或者
Thread.interrupted();
(請注意,這兩者的行為是不同的。一個清除中斷標志,另一個不清除。)
或者,您可以將static
字段更改為實例字段,並使所有GetInfo
方法成為實例方法。 這意味着您可以實例化GetInfo
多個實例,每個實例都創建自己的Thread
並在實例字段中保存引用。
還有兩點:
您創建然后處理線程的方式相當低效。 (啟動線程的開銷很大。)更好的方法是重構代碼,以便它可以使用線程池。
調用你的方法StartPointerInfo
和StopPointerInfo
是StopPointerInfo
的風格。 Java 方法名稱應始終以小寫字母開頭。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.