Потоки Java и высокая загрузка ЦП - PullRequest
1 голос
/ 15 марта 2012

Я провел здесь поиск и не смог найти ответ, поэтому я думаю, что лучше спросить. Я использую немного дорогой алгоритм в простом Java-приложении Swing. Позвольте мне описать структуру:

По моему JPanel run() методу:

public void run() {
    while(true) {
        Algorithm alg = new Algorithm(signal);
        new Thread(alg).start();

        //Wait for algorithm to finish 
        signal.await(alg);

        updateInterface();

        Thread.sleep(60L);
    }
}

Алгоритм перебирает пиксели файла .JPG, затем перебирает другой большой массив Integer (длина ~ 12000) и возвращает результат. Там очень нет лишних дорогих расчётов. Я также называю Thread.sleep(60L) в методе Алгоритм run().

Метод udpateInterface() очень быстрый, просто нарисуйте несколько java.awt.Polygon объектов.

Несмотря на то, что я звоню Thread.sleep(60L), загрузка моего компьютера Mac Book составляет около 160% (Intel Core 2 Duo 2,4 ГГц, Mem 4GB 1067).

Есть ли способ, которым я могу запустить это, не плавя мой компьютер? Я использую CountDownLatch как механизм уведомления об ожидании.

Спасибо!

Ответы [ 4 ]

4 голосов
/ 15 марта 2012

Я бы использовал следующий шаблон для планирования повторяющейся задачи.

private ScheduledExecutorService executorService = null;

public void start() {
    if (executorService != null && !executorService.isShutdown()) return;

    executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                Algorithm alg = new Algorithm(signal);
                alg.run();
                updateInterface();
            }
        }, 0, 60, TimeUnit.MILLISECONDS);
}

public void stop() {
    if (executorService != null)
        executorService.shutdown();
}
2 голосов
/ 15 марта 2012

Нет смысла начинать другой поток, если все, что вы собираетесь сделать после этого, - заставить текущий поток дождаться завершения другого.Вы также можете просто запустить алгоритм в потоке, который у вас уже есть;в любом случае, вы не будете переходить к updateInterface() до тех пор, пока алгоритм не будет завершен.

Как уже отмечали другие, после завершения работы алгоритма и обновления пользовательского интерфейса вы только ждете 60 миллисекунд, прежде чем запуститьалгоритм снова.Похоже, ваша программа тратит большую часть своего времени на выполнение алгоритма.Это нормально, если вам нужно это для быстрого обновления экрана, но в противном случае вы можете использовать более длительную задержку.

Кроме того, вы запускаете новый поток каждый раз в цикле.Этот поток запускает алгоритм один раз и затем завершается, или он запускает алгоритм в цикле?Если у вас есть циклы, запускающие потоки, каждый из которых является длительным циклом, интенсивно использующим процессор, вы можете случайно запустить много копий алгоритма одновременно.Если вы ожидаете, что поток алгоритма прекратит работу после того, как он вас проинформирует, вы должны join() проверить это.

2 голосов
/ 15 марта 2012

160% загрузка ЦП относится к одному ядру вашей машины, то есть максимально возможное на вашей машине составляет 200%, поскольку оно имеет два ядра.Вы не расплавляете свой процессор.

1 голос
/ 15 марта 2012

Сколько ждать ты хочешь? Если вы хотите подождать 60 секунд, вы должны использовать 60000L, поскольку время указывается в миллисекундах.

...