簡體   English   中英

我的計時器線程可能正在用Thread.sleep欺騙他?

[英]My timer's thread may be cheating on him with Thread.sleep?

因此,從本質上來說,我擔心在10分鍾后不會調用我的timertask的run方法,因為我正在使主線程進入睡眠狀態10秒鍾,以避免瘋狂的CPU使用率整天運行在一個空的while循環中。 這是java main方法的代碼。

 private static boolean testDone = false;
 public static void main(String[] args)
 {
        final int minutes = 10;
        final StressTest test = new StressTest(someParams);

        test.start();

        Timer timer = new Timer();
        timer.schedule(new TimerTask(){

            @Override
            public void run() {

                testDone = true;
                int completedSynths = test.stop();
                System.out.println("Completed Synths: " + completedSynths);
                System.out.println("Elapsed Time in Minutes: " + minutes);
                System.out.println("Throughput (synths/min): " + completedSynths/minutes);

            }}, minutes*60*1000);

        while(!testDone)
        {
            System.out.println("Still not done... sleeping for 10 secs....");
            Thread.sleep(10000);
        }

        System.exit(0);

更瘋狂的是, while循環中的System.out從不打印。 我做了什么??

編輯:為StressTest對象添加偽代碼

public class StressTest 
{

    private SecureRandom random = new SecureRandom();

    private volatile int completedSynths = 0;

    private volatile boolean shouldStop = false;

    private Thread[] threads;

    /**
     * Instantiate a new StressTest object.
     * 
     * @param threadCount number of concurrent threads to be polling server
     */
    public StressTest(int threadCount)
    {
        threads = new Thread[threadCount];
    }

    public void start()
    {
        System.out.println("Starting Stress Test....");

        for(int i = 0; i < threads.length; i++)
        {
            Runnable synthCaller = new SynthApiCaller();
            threads[i] = new Thread(null, synthCaller, "SynthThread" + i);
            threads[i].run();
        }
    }

    public int stop()
    {
        System.out.println("Stopping Stress Test...");
        shouldStop = true;

        return completedSynths;
    }

    private String randId()
    {
        return new BigInteger(130, random).toString(32);
    }

    private class SynthApiCaller implements Runnable
    {
        @Override
        public void run() 
        {
            while(!shouldStop)
            {
                try 
                {
                            //this class makes an HTTP request to a server and then writes result to a file
                    MyClass.writeFile( "someFileLoc/file.data");
                    completedSynths++;

                    Runtime.getRuntime().exec("rm -r " + fileLoc);
                    System.out.println("Synth # " + completedSynths);
                } 
                catch (IOException e) 
                {
                    System.out.println(e.getMessage());
                }
            }

            System.out.println("Thread terminated...");
        }

    }
}

我擔心在10分鍾后不會調用我的timertask的run方法,因為我正在使主線程進入睡眠狀態10秒鍾

主線程中的Thread.sleep(...)不會影響Timer的運行。 如果計時器在10分鍾后沒有運行,那么test.stop()是否可能阻塞?

重要的是要意識到,如果測試在主線程中啟動,然后在Timer線程中停止,則必須進行一些同步。 我假設測試正在另一個線程中運行。 您可能需要將它同步,然后在Timer線程內部調用類似於:

synchronized (test) {
    test.start();
}

如果您不熟悉Java同步,可以在線上找到一些不錯的教程

如果您想知道是否完全調用了計時器,我將在您的計時器任務中設置一個斷點,其中將其設置為testDone = true然后查看它是否到達那里。 這是一個在eclipse中使用調試器好教程

更瘋狂的是,while循環中的System.out從不打印。 我做了什么??

正如@assylias所提到的,while循環中未顯示的System.out(...)必須表示testDone設置為true。 由於testDone正在不同的線程中進行更新和訪問,因此您需要確保它也是volatile


我只是在沒有test.start()stop()情況下運行了您的代碼示例,它似乎運行良好。 問題可能出在您的test代碼中。

Still not done... sleeping for 10 secs....
Still not done... sleeping for 10 secs....
...
Completed Synths: 1
Elapsed Time in Minutes: 10
Throughput (synths/min): 0

現在你已經添加了更多代碼,這里有一些評論:

  • completedSynths++; 應該更改為AtomicInteger ++不是原子操作,因此即使字段是可變的,多個線程也可以覆蓋彼此的增量。

  • 如果您試圖等待線程完成,而不是等待10分鍾,我建議使用thread[i].join()調用thread[i].join() 更好的方法是使用ExecutorService並使用awaitTermination(...)方法。

  • 您調用shouldStop = true; 然后返回completedSynths; 您可能希望等待線程完成或某事。

  • 我不會將null ThreadGroup傳遞給Thread構造函數。 只需使用不帶ThreadGroup的構造函數即可。

我建議讓testDone變得不穩定。 實際上,除了進行更改的線程外,我看不到任何迫使對testDone進行更改的結果可見於線程中的讀取。

暫無
暫無

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

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