Что происходит, когда политика поточной обработки Swing нарушена?

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

Вот почему Java имеет TreeMap, (в дополнение к TreeSet, TreeList, ArrayList и реализациям LinkedList Списка.)

  • А TreeSet сохраняет вещи в объектном порядке сравнения. Ключ определяется интерфейсом Comparable.

  • А LinkedList сохраняет вещи в порядке вставки.

  • ArrayList использует больше памяти, быстрее для некоторых операций.

  • А TreeMap, точно так же устраняет необходимость отсортировать по ключу. Карта создается в ключевом порядке во время вставок и сохраняется в отсортированном порядке в любом случае.

Однако по некоторым причинам, реализация Java TreeSet вполне немного медленнее, чем использование ArrayList и вида.

[Трудно размышлять относительно того, почему это было бы существенно медленнее, но это. Это должно быть немного быстрее одной передачей через данные. Такого рода вещь часто является стоимостью управления памятью, превосходящего алгоритмический анализ.]

6
задан Michael Myers 15 September 2009 в 21:36
поделиться

5 ответов

От «Ничего» до периодически возникающих проблем до «Все сломалось, позвольте всем работать над графическим интерфейсом!»

Главный (наиболее очевидный) визуальный эффект заключается в том, что если вы задержите графический интерфейс поток (например, кто-то нажимает кнопку, и вы ложитесь спать (5000) или что-то в этом роде), ваш графический интерфейс не перерисовывается. Это невозможно, потому что вы держитесь за единственную нить, которую ей позволено передать вам! Это заставляет людей думать, что Java действительно медленная. Это неплохо, но это достаточно легко запрограммировать, чтобы многие люди, не утруждающие себя исследованием подобных практик, создали продукты для доставки.

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

Наконец, редко (или часто, если вы вызываете компонент Swing в жестком цикле не в том потоке) вы можете получить конфликты потоков . Если это произойдет, может возникнуть (или нет) исключение, и что-то, вероятно, будет отображаться неправильно, но это может быть неочевидно.

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

Наконец, редко (или часто, если вы вызываете компонент Swing в жестком цикле не в том потоке) вы можете получить конфликты потоков . Если это произойдет, может быть сгенерировано исключение (или нет), и что-то, вероятно, будет отображаться неправильно, но это может быть неочевидно.

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

Наконец, редко (или часто, если вы вызываете компонент Swing в жестком цикле не в том потоке) вы можете получить столкновения потоков . Если это произойдет, может быть сгенерировано исключение (или нет), и что-то, вероятно, будет отображаться неправильно, но это может быть неочевидно.

3
ответ дан 10 December 2019 в 00:41
поделиться

1) Является ли иногда законным выполнение всех этих вызовов извне потока Swing?

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

2) Какое влияние на поток Swing и почему пользовательский интерфейс менее отзывчив, когда я вызываю его извне?

Ну, EDT отвечает за обновление GUI. Если вы звоните извне, это не «менее отзывчиво» - оно » s, что фактические системные вызовы низкого уровня, обновляющие пользовательский интерфейс, не выполняются (вообще). Что, вероятно, происходит в вашем приложении, так это то, что оригинальным разработчикам повезло и они меняют состояние в компоненте Swing, не создавая действительно неприятных условий гонки. Затем какое-то другое событие вызывает перерисовку EDT, что приводит к обновлению компонента. Может показаться, что это «отсутствие отзывчивости», но на самом деле происходит «отсутствие обновления экрана».

EDT - это просто обычный поток, но он немного особенный тем, что выполняется в тесном цикле. который обрабатывает сигналы, связанные с графическим интерфейсом пользователя (например, команды рисования). Семантеки размещения этих типов команд на EDT действительно, действительно отличается от того, что мы обычно называем потоками Java (это включает отправку операций в насос сообщений).

Короче и короче - все те документы Javadoc, которые говорят «взаимодействовать только с объектами Swing на EDT», написаны не просто так. Не связывайся с этим. Если вы хотите выполнить фоновую обработку, прекрасно, но вы несете ответственность за проксирование взаимодействия с компонентами J * обратно в EDT (обычно с помощью invokeLater ()).

3
ответ дан 10 December 2019 в 00:41
поделиться
  1. There really are no exceptions. Kevin is partially correct - the JTextComponent.setText() is advertised as thread safe. However, looking at the 1.6 code, it provides synchronization on the document object and does not use the EDT. This is fine, unless another swing component (or something that controls swing components) is listening to the document object. Save yourself the trouble of worrying about it, and just always use the EDT - like Kevin says, there really are no situations (that I'm aware of) to do otherwise.

  2. Hard to say without digging into the code; the behavior is undefined. If your background tasks were long running (> a few seconds), you'd see the opposite effect - using the EDT will make the UI unresponsive while your tasks are running.

Fortunately, it sounds like doing it the right way is working best for you anyway. :)

Sun used to say it was ok to use other threads with components that haven't been realized, but later recanted:

Related stackoverflow question

Check out Sun's UI tutorial on swing and concurrency (I'd post the link, but this is my first answer on stackoverflow0.

2
ответ дан 10 December 2019 в 00:41
поделиться

Основная проблема заключается в том, что небезопасные для потоков объекты выполняются в многопоточном режиме. Даже такая простая вещь, как чтение HashMap , может попасть в бесконечный цикл. Поскольку AWT использует блокировки (плохо), вы также можете столкнуться с тупиками. Тем не менее, вам, скорее всего, это сойдет с рук, хотя вы можете обнаружить, что обновленная версия Java внезапно вызывает проблемы на некоторых клиентских машинах.

(Кстати: это поток диспетчеризации событий AWT, а не Swing.)

1
ответ дан 10 December 2019 в 00:41
поделиться

Для (1) на практике все, что обновляет пиксели на экране, должно вызываться из потока диспетчеризации событий (EDT) . Если некоторые JVM могут приемлемо обрабатывать обновления извне EDT, вы никогда не должны полагаться на эту работу, некоторые машины и другой внешний вид не будут работать приемлемо. Поведение не определено - и этим можно объяснить наблюдаемое вами отсутствие реакции.

1
ответ дан 10 December 2019 в 00:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: