Лучше всего программируя подход/методологию для уверения потокобезопасности

Транспортир использует дополнительные крючки для плагинов и разрешает их в дополнение к крючкам Жасмин. Они обычно решаются в Protractor's Runner. Вы можете прочитать о плагинах здесь: https://github.com/angular/protractor/blob/master/lib/plugins.ts#L25

Так, например, [110 ] Плагин проверяется в конфигурации ( https://github.com/angular/protractor/blob/selenium4/lib/runner.ts#L63 ) и выполняется бегуном ( https: / /github.com/angular/protractor/blob/selenium4/lib/runner.ts#L82). Эти два файла, на которые ссылается бегун, предназначены для ветви обновления Селена 4. Эти версии легче смотреть, поскольку в них нет цепочки обещаемых обещаний.

8
задан Lawrence Dol 6 November 2008 в 19:41
поделиться

14 ответов

Существует много методов, которые входят в общедоступное сознание сейчас (как в: последние несколько лет). Большой был бы агентами. Это - что-то, что Erlang сначала принес к железу сетки, но который был продвинут более новыми языками как Scala (агенты на JVM). В то время как это верно, что агенты не решают каждую проблему, они действительно делают намного легче рассуждать о Вашем коде и определить горячие точки. Они также делают намного более простым разработать параллельные алгоритмы из-за способа, которым они вынуждают Вас использовать продолжение, передающее по общему изменяемому состоянию.

Ветвление/Соединение - что-то, что необходимо посмотреть на, особенно если Вы находитесь на JVM. Doug Lea написал оригинальную работу по теме, но многие исследователи обсудили ее за эти годы. Насколько я понимаю ссылочная платформа Doug Lea планируется для включения в Java 7.

На немного менее - агрессивный уровень, часто единственные шаги, необходимые для упрощения многопоточного приложения, должны только уменьшить сложность блокировки. Мелкомодульная блокировка (в стиле Java 5) является большой для пропускной способности, но очень очень трудной разобраться. Один альтернативный подход к блокировке, которая наращивает некоторые обороты через Clojure, был бы транзакционной программным обеспечением памятью (STM). Это - по существу противоположность стандартной привязки, что это оптимистично, а не пессимистично. Вы начинаете путем предположения, что у Вас не будет коллизий, и затем позволять платформе решать проблемы, если и когда они произойдут. Базы данных часто прокладывают себе путь. Это является большим для пропускной способности в системах с низким уровнем аварийности, но большая победа находится в логической компонентизации Ваших алгоритмов. Вместо того, чтобы произвольно связывать блокировку (или серия блокировок) с некоторыми данными, Вы просто переносите опасный код в транзакцию и позволяете платформе выяснить остальных. Можно даже получить немного времени компиляции, выехав из достойных реализаций STM как монада GHC STM или мой экспериментальный Scala STM.

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

6
ответ дан 5 December 2019 в 05:35
поделиться

Похож на Ваш МОК, несколько подобно FBP :-) Это было бы фантастически, если код JavaFBP мог бы получить полную проверку от кого-то как себя сведущий в искусстве написания ориентированного на многопотоковое исполнение кода... Это находится на SVN в SourceForge.

0
ответ дан 5 December 2019 в 05:35
поделиться

Ядро касается, поскольку я видел их, были (a) предотвращение мертвых блокировок и (b) обмен данными между потоками. Беспокойство арендодателя (но незначительно арендодатель) избегало узких мест. Я уже встретился с несколькими проблемами с разрозненным из мертвых блокировок порождения блокировки последовательности - это должно очень хорошо сказать, "всегда получают, привязывает тот же порядок", но в средней и крупной системе это часто является практически говорящим невозможное гарантировать это.

Протест: Когда я предложил это решение, я должен был быть нацелен на Java 1.1 (таким образом, пакет параллелизма еще не был мерцанием в глазу Doug Lea) - инструменты под рукой полностью синхронизировались и ожидают/уведомляют. Я привлек опыт, пишущий сложную многопроцессную коммуникационную систему с помощью основанной на сообщении системы в реальном времени QNX.

На основе моего опыта с QNX, который имел беспокойство мертвой блокировки, но избежал параллелизма данных путем привыкания сообщений от пространства памяти одного процесса до anothers, я придумал основанный на сообщении подход для объектов - который я назвал МОК для межобъектной координации. В начале, которое я предусмотрел, я мог бы создать все свои объекты как это, но задним числом оказывается, что они только необходимы в главных контрольных точках в крупном приложении - "межгосударственные обмены", если Вы будете, не подходящий для каждого "пересечения" в дорожной системе. Это оказывается главным преимуществом, потому что они - вполне неPOJO.

Я предусмотрел систему, где объекты концептуально не вызовут синхронизированные методы, но вместо этого "отправили бы сообщения". Сообщения могли быть, отправляют/отвечают, где отправитель ожидает, в то время как сообщение обрабатывается и возвращается с ответом, или асинхронный, где сообщение отбрасывается на очереди и исключается из очереди и обрабатывается на более позднем этапе. Обратите внимание, что это - концептуальное различие - обмен сообщениями был реализован с помощью вызовов синхронизированного метода.

Базовыми объектами для системы обмена сообщениями является IsolatedObject, IocBinding и IocTarget.

IsolatedObject так называется, потому что он не имеет никаких открытых методов; это - это, которое расширяется, чтобы получить и обработать сообщения. Используя отражение это далее осуществляется, что дочерний объект не имеет никаких открытых методов, ни любого пакета или защищенных методов кроме наследованных от IsolatedObject, почти все из которых являются окончательными; это выглядит очень странным сначала, потому что при разделении на подклассы IsolatedObject Вы создаете объект с 1 защищенным методом:

Object processIocMessage(Object msgsdr, int msgidn, Object msgdta)

и вся остальная часть методов является закрытыми методами обработать определенные сообщения.

IocTarget является средством абстракции видимости IsolatedObject и очень полезен для предоставления другого объекта самоссылки для передачи обратно сигналов Вам, не выставляя Вашу ссылку фактического объекта.

И IocBinding просто связывает объект отправителя с получателем сообщения так, чтобы проверки проверки не были понесены для каждого сообщения, отправленного, и создается с помощью IocTarget.

Все взаимодействие с изолированными объектами посредством "отправки", это обменивается сообщениями - processIocMessage метод получателя синхронизируется, который гарантирует, что только одно сообщение быть обработанным за один раз.

Object iocMessage(int mid, Object dta)
void   iocSignal (int mid, Object dta)

Создав ситуацию, где вся работа, сделанная изолированным объектом, направляется через отдельный метод, я затем расположил объекты в заявленной иерархии посредством "классификации", которую они объявляют при построении - просто строка, которая определяет их как являющийся одним из любого количества "типов получателя сообщения", который помещает объект в некоторой предопределенной иерархии. Затем я использовал код доставки сообщений гарантировать, что, если отправителем был самостоятельно IsolatedObject, которые для синхронного отправляют/ответными сообщения, это было то, которое ниже на иерархии. Асинхронные сообщения (сигналы) отправлены получателям сообщения с помощью отдельных потоков в пуле потоков, кто все задание, поставляют сигналы, поэтому сигналы могут быть, отправляют с любого объекта на любой получатель в системе. Банка сигналов может поставить любые желаемые данные сообщения, но не ответ возможно.

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

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

Поскольку любой данный получатель обрабатывает только одно сообщение за один раз, и потому что это не имеет никаких других точек входа, все соображения объектного состояния устраняются - эффективно, объект полностью синхронизируется, и синхронизация не может случайно быть брошена никакой метод; никакие методы считывания, возвращая устаревшие кэшируемые данные потока и никакие методы set, изменяющие объект, не указывают, в то время как другой метод действует на него.

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

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

Обратите внимание, что это не используется для более простых ситуаций, где рабочие потоки с помощью более стандартных пулов потоков будут достаточны (хотя я буду часто вводить результаты рабочего назад в основную систему путем отправки сообщения МОК). И при этом это не используется для ситуаций, куда поток уходит и делает что-то абсолютно независимое от остальной части системы, такой как поток сервера HTTP. Наконец, это не используется для ситуаций, где существует координатор ресурса, который само не взаимодействует с другими объектами и где внутренняя синхронизация сделает задание без риска мертвой блокировки.

Править: Я должен был заявить, что сообщения, которыми обмениваются, должны обычно быть неизменными объектами; при использовании изменяемых объектов действие отправки это нужно считать рукой и заставить отправителя оставлять все управление и предпочтительно не сохранять ссылки на данные. Лично, я использую блокируемую структуру данных, которая заблокирована кодом МОК и поэтому становится неизменной при отправке (флаг блокировки энергозависим).

0
ответ дан 5 December 2019 в 05:35
поделиться

Я вспоминаю быть несколько потрясенным обнаружить, что synchronizedList класс Java не был полностью ориентирован на многопотоковое исполнение, но только условно ориентирован на многопотоковое исполнение. Я мог все еще быть записан, если бы я не переносил свои доступы (итераторы, методы set, и т.д.) в синхронизируемом блоке. Это означает, что я, возможно, уверил свою команду и свое управление, что мой код был ориентирован на многопотоковое исполнение, но я, возможно, был неправ. Иначе я могу гарантировать, что потокобезопасность - чтобы инструмент проанализировал код, и имейте его передача. STP, модель Actor, Erlang, и т.д. является некоторыми способами получить последнюю форму обеспечения. Способность гарантировать свойства программы надежно / быть огромным шагом вперед в программировании.

0
ответ дан 5 December 2019 в 05:35
поделиться

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

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

0
ответ дан 5 December 2019 в 05:35
поделиться

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

Я услышал, что люди спорят (и согласитесь с ними), что традиционная модель потоков действительно не будет работать, входя в будущее, таким образом, мы будем оказываться перед необходимостью разрабатывать другой набор парадигм / языки для реального использования этих новомодных мультиядер эффективно. Языки как Haskell, программы которого легко parallelizable начиная с любой функции, которая имеет побочные эффекты, должны быть явно отмечены тот путь и Erlang, о котором я, к сожалению, не знаю так много.

0
ответ дан 5 December 2019 в 05:35
поделиться

Я обычно следую за подходом стиля Erlang. Я использую Шаблон Активного объекта. Это работает следующим образом.

Разделите свое приложение на очень крупномодульные единицы. В одном из моих текущих приложений (400 000 LOC) у меня есть appr. 8 из этих крупномодульных единиц. Эти единицы не совместно используют данных вообще. Каждая единица сохраняет свои собственные локальные данные. Каждая единица работает на своем собственном потоке (= Шаблон Активного объекта) и следовательно является единственной, распараллелил. Вам не нужны никакие блокировки в единицах. Когда единицы должны отправить сообщения в другие единицы, они делают это путем добавления сообщения очереди других единиц. Другая единица выбирает сообщение от очереди и воздействует на то сообщение. Это могло бы инициировать другие сообщения к другим единицам. Следовательно, единственное привязывается, этот тип приложения вокруг очередей (одна очередь и блокировка на единицу). Эта архитектура является мертвой блокировкой, бесплатной по определению!

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

Путем деления приложения на единицы помнят. Оптимальное количество длительных потоков на ядро процессора равняется 1.

4
ответ дан 5 December 2019 в 05:35
поделиться

Нет никакого Истинного Ответа для потокобезопасности в Java. Однако существует по крайней мере одна действительно замечательная книга: Параллелизм Java на практике. Я регулярно обращаюсь к нему (особенно версия Safari онлайн, когда я нахожусь на перемещении).

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

5
ответ дан 5 December 2019 в 05:35
поделиться

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

Основной пример:

thread1_proc() {

msg = get_queue1_msg(); // block until message is put to queue1
threat1_msg(msg);

}

thread2_proc() {
msg = create_msg_for_thread1();
send_to_queue1(msg);
}

Это - типичный пример потребительской проблемы производителя.

0
ответ дан 5 December 2019 в 05:35
поделиться
  1. Постарайтесь не обмениваться данными между потоками, где возможный (копируют все).
  2. Никогда не имейте, соединяет вызовы метода внешних объектов, если это возможно.
  3. Сохраните блокировки для самого короткого количества времени возможными.
5
ответ дан 5 December 2019 в 05:35
поделиться

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

1/Позволяют каждому потоку выполнить свое собственное время жизни (т.е. решите, когда умереть). Это может быть запрошено снаружи (скажите что переменная флага), но это в совершенно ответственном.

2/Имеют все потоки, выделяют и освобождают их ресурсы в том же порядке - это гарантирует, что мертвой блокировки не произойдет.

Ресурсы Блокировки 3/в течение самого короткого возможного времени.

Ответственность за Передачу 4/за данные с самими данными - после того как Вы уведомляете поток, что данные - для обработки, оставьте их в покое, пока ответственность не отдана Вам.

7
ответ дан 5 December 2019 в 05:35
поделиться

Я предлагаю модель агента.

0
ответ дан 5 December 2019 в 05:35
поделиться

Некоторые эксперты считают, что ответ на ваш вопрос - вообще избегать цепочек, потому что почти невозможно избежать непредвиденных проблем. Процитируем Проблема с потоками :

Мы разработали процесс, включающий система оценки зрелости кода (с четырьмя уровнями: красный, желтый, зеленый и синий), обзоры дизайна, код обзоры, ночные сборки, регрессионные тесты и автоматические метрики покрытия кода. Часть ядра, обеспечивающего единообразное представление структуры программы, было написано в начале 2000 г., дизайн был отмечен желтым цветом, а код - зеленым. В число рецензентов вошли эксперты по параллелизму, не только неопытные аспиранты (Кристофер Хайлендс (ныне Брукс), Барт Кинхуис, Джон Реки и [Эд Ли] были рецензентами). Мы написали регрессионные тесты, которые достигли 100% кода. покрытие ... Сама система ... начала широко использоваться, и каждое использование системы осуществляло это код. Никаких проблем не наблюдалось до тех пор, пока код не зашел в тупик 26 апреля 2004 г., четыре года спустя.

0
ответ дан 5 December 2019 в 05:35
поделиться

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

В Википедии есть хорошие статьи на эту тему:

http://en.wikipedia.org/wiki/Dataflow_programming

http://en.wikipedia.org/wiki/Flow-based_programming

Кроме того, у него есть несколько преимуществ, таких как невероятно гибкая конфигурация, многослойность; программист (программист компонентов) не должен программировать бизнес-логику, это делается на другом этапе (создание сети обработки).

Знаете ли вы, что make - это система потока данных? Посмотрите make -j, особенно если у вас многоядерный процессор.

3
ответ дан 5 December 2019 в 05:35
поделиться
Другие вопросы по тегам:

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