Как иметь дело с Параллелизмом, прежде чем Вы начнете кодировать

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

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

Разговор в самых общих чертах, какие методы я должен использовать при решении, как мое приложение должно 'течь' со всеми моими потоками, входящими в узел?

16
задан Tom R 29 January 2010 в 22:52
поделиться

9 ответов

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

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

1
ответ дан 30 November 2019 в 22:17
поделиться

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

0
ответ дан 30 November 2019 в 22:17
поделиться

Читайте на параллельных языках, а если вы еще учитесь в колледже, то лучше пройдите курс по параллельному программированию для выпускников. См. Учебники по Java: Урок: параллельное программирование . Одной из известных книг по параллельному программированию на Java является Java Concurrency in Practice . Java так много встроена в фреймворк для решения вопросов параллелизма, включая параллельные коллекции и синхронизированные методы .

Java Concurrency in Practice http://ecx.images-amazon.com/images/I/51Hx%2Bg4Q6QL._BO2,204,203,200-76_AA240_SH20_OU01_.jpg

5
ответ дан 30 November 2019 в 22:17
поделиться

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

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

Редактировать:

Вот несколько ссылок на некоторые библиотеки, которые вы могли бы использовать в вашем следующем проекте. Есть Duce STM , что, поскольку имени подразумевает реализацию STM для Java. Тогда есть акт Actorfoundry , в качестве имени подразумевает, является моделью актера для Java. Тем не менее, я не могу не сделать пробку для Scala со своими встроенными в модели актера.

5
ответ дан 30 November 2019 в 22:17
поделиться

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

Вы говорите, списки бросают CONCULLENTMODICITIONEXCECTION. Я принимаю это, что ваши списки выберены отдельными потоками. Так что первое, что вы должны спросить, является ли это необходимым. Это невозможно для второго потока для работы в копии списка?

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

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

2
ответ дан 30 November 2019 в 22:17
поделиться

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

List<Item> items = new ArrayList<Item>();

//... some code adding items to the list

for (Item item : items) {
    if(item.isTheOneIWantToRemove()) {
        items.remove(item); //This will result in a ConcurrentModificationException
    }
}

изменение вашего цикла в цикл с итератором или увеличением значения индекса решает проблему:

for (Iterator<String> it = items.iterator(); it.hasNext();) {
    if(item.isTheOneIWantToRemove()) {
        it.remove(); //No exception thrown
    }
}

или

for (int i = 0; i < items.size(); i++) {
    if(item.isTheOneIWantToRemove()) {
        items.remove(items.get(i)); //No exception thrown
    }
}
2
ответ дан 30 November 2019 в 22:17
поделиться
  1. Старайтесь использовать коллекции из пакета Java.util.concurrent или даже более улучшенные сборники коллекций Google.
  2. Читайте о использовании синхронизированных блоков
0
ответ дан 30 November 2019 в 22:17
поделиться

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

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

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

С другой стороны, некоторые клиенты могут получать доступ к совершенно различным данным. Так, если мы предполагаем, что CachingDBProxy только прячет ограниченный доступ объема данных про запас одной группой клиентов, может выбросить данные, все еще необходимые другой группе клиентов, вызвав ухудшение функционирования тайника. В этом случае может быть разумным иметь несколько CedingDBProxies, даже если существует только одна база данных (это, конечно, предполагает, что возможен параллельный доступ).

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

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

-121--3367053-

На основании комментария Кевинса:

foreach(Button b in MyForm.Controls.OfType<Button>())
{
    b.Click += Button_Click;
}

void Button_Click(object sender, EventArgs e)
{
    Button clickedButton = sender as Button;
}
-121--4746359-

Параллелизм сводится к управлению общим состоянием.

"Все проблемы параллелизма сводятся к координация доступа к изменяемому состоянию. Чем менее изменяемое состояние, тем легче обеспечивает безопасность резьбы. " - Java Concurrency in Practice

Таким образом, вы должны задать себе вопрос:

  • Каковы присущие общие данные, которые потребуются моему приложению?
  • Когда поток может работать над снимком данных, то есть это мгновенная работа над клоном общих данных?
  • Могу ли я идентифицировать известные образцы и использовать абстракцию более высокого уровня, а не низкоуровневые блокировки и координацию потоков, Например, очереди, исполнитель и т.д.?
  • Подумайте о глобальной схеме блокировки, чтобы избежать взаимоблокировки и иметь последовательное получение блокировок

Самый простой подход к управлению общим состоянием состоит в сериализации каждого действия. Однако этот грубый подход приводит к высокому конфликту блокировок и низкой производительности.Управление параллелизмом можно рассматривать как упражнение оптимизации, в котором вы пытаетесь уменьшить конкуренцию. Итак, последующие вопросы:

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

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

  • Где можно ослабить некоторые ограничения и принять, что иногда вещи не будут на 100% правильными (например, счетчик)?
  • Могу ли я быть оптимистом и справляться с конфликтами только тогда, когда происходят параллельные изменения (например, использование временной метки и логики повтора - это то, что делает ТМ)?

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

6
ответ дан 30 November 2019 в 22:17
поделиться

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

http://javatip.com/2010/07/core-java/concurrency/thread-safe-without-synchronization

-1
ответ дан 30 November 2019 в 22:17
поделиться
Другие вопросы по тегам:

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