2

ここのガイド 、つまり実際の単純なファイル IO tick-tock コードに基づいて、Linux ディストリビューションに Java サービスを正常に展開しましたが、このような単純なプログラムの CPU 使用率が高いことに気付きました。おそらく、スレッドが常にチェックしているためです...

NetBeans を使用して CentOS で実際の JAR ファイルを構築し、次に Arch Linux ARM ディストリビューションにデプロイし、次に a) Oracle の Java SE Embedded JVM (v7) および b) java-7-openjdk JVM を使用しました。

問題は、CPU 使用率が jsvc によって 80 ~ 95% の間で常に変動していることです。CPUがそこまで上がるとは思っていませんでした。実際の jsvc 呼び出しで、バックグラウンド プロセスに -server パラメータを追加しようとしましたが、うまくいきませんでした (取得できませんでした。これの例は、 -server パラメータが欠落しているかどうかを除外できるようにするのに役立ちます。

-server オプション以外に何か不足している可能性があると思います。私は ScheduledExecutorService を見るように言われました - おそらく改善することができますか?

あなたの考えに感謝します - ありがとう。

4

2 に答える 2

1

何をしているかにもよりますが、Thread.sleep メソッドはおそらく問題ありませんが、ScheduledExecutorService.scheduleAtFixedRate() メソッドを使用することをお勧めします。これは徹底的にテストされ、文書化されており、将来コードを保守する必要があるかもしれない他の開発者はそれに精通しているはずです。また、たとえば実行をキャンセルしたり、複数のタスクを管理したりするためのメソッドも提供します。もっと詳しく見てみましょう。

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import static java.util.concurrent.TimeUnit.*;

public class Clock {

    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private boolean lastOneWasATick = false;

    public void startClock() {

        //Define the task 
        final Runnable tickTock = new Runnable() {
            public void run() {
                System.out.println(!lastOneWasATick ? "tick" : "tock");
                lastOneWasATick = !lastOneWasATick;
            }
        };      

        //Schedule the task's execution at 1 second intervals, starting immediately
        final ScheduledFuture<?> tickTockThreadHandle = scheduler.scheduleAtFixedRate(tickTock, 0, 1, SECONDS);

        //Stop the clock after 1 minute
        scheduler.schedule(new Runnable() {
            public void run() {
                tickTockThreadHandle.cancel(true);
            }
        }, 60, SECONDS);
    }
}
于 2014-02-17T08:37:09.840 に答える
1

そのため、nosの提案でスレッドの一時停止を追加し、問題を修正しました。次のようにコードします。

        @Override
        public void run() {                 

            while(!stopped){

                long now = System.currentTimeMillis();
                if(now - lastTick >= 10000){
                    System.out.println(!lastOneWasATick ? "tick" : "tock");
                    lastOneWasATick = !lastOneWasATick;
                    lastTick = now; 
                }

                //ADDED THIS BLOCK
                try {
                    Thread.sleep(15000);
                } catch (InterruptedException ex) {
                    //Logger.getLogger(JDaemon.class.getName()).log(Level.SEVERE, null, ex);
                }
                //END BLOCK
            }

        }
于 2014-02-17T07:24:56.123 に答える