Каково правильное поведение фонового процесса для Java-приложения без графического интерфейса? - PullRequest
3 голосов
/ 13 января 2009

Как правильно, чтобы приложение командной строки Java выполняло фоновую работу, не перегружая ресурсы? Должен ли он использовать sleep () в цикле или есть более элегантный / эффективный способ?

Ответы [ 4 ]

9 голосов
/ 13 января 2009

Некоторые эвристики:

  • Не пытайтесь принимать решения о планировании в вашем приложении. Планировщик операционной системы намного лучше, чем ваш. Пусть это сделает свое дело.
  • Не опрашивайте, если не нужно. Например, вместо того, чтобы спать n секунд, затем просыпаться, чтобы проверить незаблокированный сокет, заблокировать сокет. Эта вторая стратегия лучше работает с планировщиком операционной системы.
  • Не используйте огромную кучу, если вам не нужно, и старайтесь не выделять огромные куски памяти за один раз. Удачное приложение, как правило, отрицательно влияет на производительность системы.
  • Использовать буферизованный ввод / вывод. Всегда. Если вы думаете, что вам нужен небуферизованный ввод / вывод, будьте абсолютно уверены, что вы правы. (Вы, вероятно, ошибаетесь.)
  • Не создавайте много тем. Нитки на удивление дороги; после определенной точки, большее количество потоков уменьшит профиль производительности вашего приложения. Если у вас много работы одновременно, изучите и используйте java.util.concurrent.

Конечно, это просто стартовый список ...

3 голосов
/ 13 января 2009

Я бы использовал sleep () только в том случае, если нет никакой работы. Например, если вы делаете что-то вроде периодического опроса очереди задач и там ничего нет, поспите некоторое время, затем проверьте снова и т. Д.

Если вы просто пытаетесь убедиться, что процессор не перегружен, но все еще выполняете реальную работу, вы можете периодически вызывать Thread.yield (). Это откажется от управления процессором и позволит другим потокам работать, но это не усыпит вас. Если другим процессам не нужен процессор, вы вернете контроль и продолжите выполнять свою работу.

Вы также можете установить свой поток с низким приоритетом: myThread.setPriority (Thread.MIN_PRIORITY);

Как сказал Измаил, не делайте этого в своей основной теме. Вместо этого создайте «рабочий поток». Таким образом, ваш пользовательский интерфейс (GUI или CLI) будет по-прежнему отзывчивым.

2 голосов
/ 13 января 2009

Есть несколько способов. Я бы использовал ExecutorService ... например:

ExecutorService service = Executors.newCachedThreadPool();

Callable<Result> task = new Callable<Result>() {
    public Result call() throws Exception {
        // code which will be run on background thread
    }
};

Future<Result> future = service.submit(task);

// Next line wait until background task is complete
// without killing CPU. Of course, you can do something
// different here and check your 'future' later.
//
// Note also that future.get() may throw various exceptions too,
// you'll need to handle them properly

Result resultFromBackgroundThread = future.get();

Это код Java 5, ExecutorService, Callable, Future и аналогичные в пакете java.util.concurrent.

1 голос
/ 13 января 2009

Для начала нужно убедиться, что используются только эти ресурсы, а не другие объекты (чтобы они стали собирать мусор).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...