簡體   English   中英

Java中線程的正確方法

[英]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並在實例字段中保存引用。


還有兩點:

  • 您創建然后處理線程的方式相當低效。 (啟動線程的開銷很大。)更好的方法是重構代碼,以便它可以使用線程池

  • 調用你的方法StartPointerInfoStopPointerInfoStopPointerInfo的風格。 Java 方法名稱應始終以小寫字母開頭。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM