Советы по кодированию Java-программ в многоядерном сценарии [закрыто]
-
03-07-2019 - |
Вопрос
Кажется, много шума вокруг многоядерности и Java.Хотя некоторые люди говорят, что поддержка Java отсутствует достаточно хорошо, это определенно то, чего стоит ожидать.Кажется, есть много методы для улучшения производительности параллельных программ.
Любые советы/советы по программированию в многоядерном сценарии приветствуются.
Решение
Изучите новые возможности параллельного выполнения Java (в разделе java.util.concurrent
упаковка), которые были добавлены в Java 5.Он обеспечивает функциональность более высокого уровня, чем обычный Thread
s, что упростит (и уменьшит вероятность ошибок) написание параллельных приложений.А Урок:Параллелизм из Учебники по Java было бы хорошим началом.
До сих пор я использовал только ExecutorService
, что позволяет производить пулы потоков, которым могут быть переданы новые задачи в единицах Runnable
или Callable
s (который может возвращать значения после выполнения как Future
s), а фактический код потоков обрабатывается ExecutorService
.
Например, выполнить некоторые вычисления с использованием пула потоков из двух потоков и получить результат можно так же просто, как:
ExecutorService es = Executors.newFixedThreadPool(2);
Future f1 = es.submit(new Callable<Integer>() {
public Integer call()
{
// Do some processing...
return someInteger;
}
});
Future f2 = es.submit(new Callable<Integer>() {
public Integer call()
{
// Do some processing...
return someInteger;
}
});
Integer firstInteger = f1.get();
Integer secondInteger = f2.get();
В приведенном выше (непроверенном) коде все, о чем мне нужно беспокоиться, это сделать пару Callable
песок submit
отдать это ExecutorService
и далее, используя Future
s, чтобы получить результат.
Загвоздка в том, что как только get
метод Future
вызывается, если обработка не завершена, программа остановится до тех пор, пока не будет получен результат Future
можно получить.Итак, в этом примере, даже если результат f2
доступен раньше f1
, программа будет ждать результата f1
доступен.
Что касается материалов для чтения, в моем списке книг, которые я скоро куплю, есть Java-параллелизм на практике Брайана Гетца, который часто возникает, когда в Java возникает вопрос о параллелизме.
А Утилиты параллелизма страница из документации Java 5 также содержит дополнительную информацию.
Другие советы
Лучший совет должен быть: выполните правильную синхронизацию!
Это может показаться несколько очевидным, но понимание Модель памяти Java жизненно важно, особенно то, как изменчивый и финальный поля работают, как синхронизированный действует как мьютекс и а барьер памяти а потом новый java.util.concurrent
конструкции, а также
Всегда хороший совет: если большинство ваших классов неизменяемы, все становится намного проще, поскольку неизменяемость устраняет необходимость беспокоиться о блокировках во многих или немногих проблемных местах.
Ознакомьтесь с предстоящими структура fork-join.Платформа fork-join позволяет разработчикам достигать детального параллелизма в многоядерных архитектурах.
Также вы можете попробовать языки на основе JVM, например Кложур которые утверждают, что упрощают многоядерное параллельное программирование.
В качестве альтернативы собственному подходу Java к параллелизму с общей памятью вы также можете рассмотреть Параллелизм на основе актеров с использованием Scala поверх Java, что обеспечивает более простую модель параллельного программирования.
Посмотрите выступление Брайана Гетца От параллельного к параллельному из Devoxx 2008.Здесь не так много советов, но они дают представление о том, куда движется параллелизм Java.
Вы можете попробовать использовать библиотеку шаблонов параллелизма, например Скандий для Явы.Просто выберите нужный шаблон параллелизма и заполните недостающие крючки.
Некоторые из шаблонов, поддерживаемых в Skandium:
- Мастер-раб:
Farm<P,R>(nested);
- Трубопровод:`Труба(стадия1, стадия2);
- Для итерации:
For<P,R>(nested, i);
- Условная итерация:
While<P,R>(nested, condition);
- Условное ветвление:
If<P,R>(condition, trueCase, falseCase);
- Уменьшение карты:
Map<P,R>(split, nested, merge);
- Map-reduce с разными путями кода:
Fork<P,R>(split, nested, merge);
- Рекурсивный разделяй и властвуй:
DaC<P,R>(condition, split, nested, merge);
Все шаблоны можно вкладывать и комбинировать, так что вы можете фармить внутри принципа «разделяй и властвуй» и т. д.
Лучшая книга с практическими советами была Java-параллелизм на практике.Ее необходимо прочитать всем Java-программистам, даже тем, кто думает, что не занимается параллельным программированием, поскольку в различных библиотеках Java имеется множество скрытых потоков (на ум приходит Swing, то же самое с сервлетами).
Мой совет:Понимание модели памяти Java (начиная с JDK 5 и выше).Большинство людей не знают, что синхронизация, изменчивость и финал имеют дополнительное значение, выходящее за рамки обычной многопоточности.
Java подходит для многопроцессорных и многоядерных систем.Если вы запрограммируете его правильно и вложите немного ума, вы получите высококонкурентную серверную систему, использующую 8 ядер, включая большую синхронизацию и так далее.Нас это вполне устраивает...JDK6 лучше, чем JDK5, а все, что ниже, не работает на многопроцессорных машинах.