Графический интерфейс Java и несколько экземпляров класса SwingWorker - PullRequest
4 голосов
/ 05 января 2010

Я делаю графический интерфейс с использованием Java (а кто нет?). Я знаю, что класс Swing Worker позволяет выполнять вычисления в фоновом режиме, предотвращая зависание графического интерфейса, но мне было интересно, может ли здесь быть что-то хорошее ...

Например, если бы было слишком много экземпляров этих фоновых потоков, повлияет ли это на производительность программы в зависимости от компьютера? Простой, но важный вопрос. Я был бы очень признателен за любой вклад. Спасибо за ваше время.

Ответы [ 3 ]

4 голосов
/ 05 января 2010

Да, чем больше обработки вы выполняете, естественно, это повлияет на производительность компьютера. В конце концов, ресурсы обработки - это ограниченный ресурс.

Тем не менее, многие современные компьютеры имеют многоядерные , что означает, что однопоточное приложение, вероятно, не сможет в полной мере использовать ресурсы процессора.

В общем, наличие нескольких работающих потоков не будет большой проблемой. Однако при наличии сотен или тысяч потоков производительность может ухудшиться, поскольку время, необходимое для выполнения переключения контекста между потоками, может начать занимать большую долю доступных ресурсов обработки.

4 голосов
/ 05 января 2010

Если вы углубитесь в код SwingWorker, вы увидите следующую определенную константу:

/**
 * number of worker threads.
 */
private static final int MAX_WORKER_THREADS = 10;

Следовательно, количество фоновых потоков никогда не может превышать это значение независимо от количества SwingWorker, которые вы фактически создаете.

Один из способов изменить модель фоновой многопоточности - подключить собственный ExecutorService к AppContext, связанному с классом SwingWorker. Однако, это немного хитро, учитывая, что AppContext принадлежит sun.awt и, следовательно, не является частью официального JDK API.

// Create single thread executor to force all background tasks to run on the same thread.
ExecutorService execService = Executors.newSingleThreadExecutor();

// Retrieve the AppContext.  *CAUTION*: This is part of the sun.awt package.
AppContext ctxt = AppContext.getAppContext();

// Verify that nothing is already associated with SwingWorker.class within the context.
Object obj = ctxt.get(SwingWorker.class);

if (obj != null) {
  throw new IllegalStateException("Object already associated with SwingWorker: " + obj);
}

// Install ExecutorService.  Will be retrieved by the SwingWorker when execute() is called.
ctxt.put(SwingWorker.class, ctxt);
2 голосов
/ 05 января 2010

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

Однако задача пользовательского интерфейса часто простаивает (ждет, пока пользователь что-то сделает). Таким образом, в 99% случаев на двухъядерном компьютере вы можете создать два рабочих потока (в дополнение к стандартному потоку пользовательского интерфейса, который всегда есть)

...