Поиск удивительной параллельной Java-программы
Поскольку я пишу профилировщик, фокусируясь на аспектах concurrency, я ищу хороший искусственный пример, используя механизмы синхронизации в Java. Мой профилировщик делает видимые действия, связанные с потоковой обработкой; например:
- вызов уведомления/ожидание
- поток изменяет свое состояние
- поток связан с другим потоком для блокировки монитора.
- блокировка монитора была получена нитью после того, как она решила его с помощью другого
- измерять время выполнения каждого метода.
- к которому поток обратился к определенному методу и как часто
- и др.
Итак, что я ищу, это Java-программа, которая, кажется, понимается под первым взглядом, но при ее запуске вы начинаете задумываться о результатах. Я надеюсь, что мой профилировщик сможет обнаружить, что происходит в фоновом режиме.
Чтобы прояснить себя, я приведу вам пример: книга Java Concurrency на практике Брайана Гетца дает "ядовитые" примеры кода, которые используются для изучения причин.
@NotThreadSafe
public class ListHelper<E> {
public List<E> list =
Collections.synchronizedList(new ArrayList<E>());
...
public synchronized boolean putIfAbsent(E x) {
boolean absent = !list.contains(x);
if (absent)
list.add(x);
return absent;
}
}
Предназначен для расширения поточно-безопасного класса методом putIfAbsent
. Поскольку list
синхронизируется, но putIfAbsent
использует другую блокировку для защиты состояния как методов, определенных в списке.
Профилировщик может отображать используемые блокировки монитора и суперпользователя (или нет...), пользователь увидит, что есть два возможных блокировки монитора вместо одного.
Мне не очень нравится этот пример, но я бы не спросил, если бы у меня было множество хороших примеров.
Я выяснил, что мой вопрос аналогичен этому: Какая самая частая проблема с w391, с которой вы столкнулись в Java? и Java Concurrency шаблоны ошибок.
Но они относятся только к разным параллельным программам. Я также ищу потокобезопасные реализации, но там, где все еще не очевидно, что они потокобезопасны.
Ответы
Ответ 1
Посмотрите список описаний описания FindBugs, в частности те, которые относятся к категории многопоточной правильности (столбец правой таблицы).
Каждая из этих ошибок содержит ссылки на то, почему конкретная идиома плоха и как ее можно решить.
Ответ 2
Я вернусь во времени, например, через семь лет или более, и найду какой-то открытый исходный код с эпохи до java.util.concurrent. Почти все, что сканировало свой собственный concurrency, будет иметь некоторые тонкие ошибки в нем, потому что concurrency трудно получить.
Ответ 3
Как насчет этого?
class ObjectReference {
private volatile Object obj = null;
public void set(Object obj) {
if (obj == null) {
throw new IllegalArgumentException();
}
this.obj = obj;
synchronized (this) {
notifyAll();
}
}
/**
* This method never returns null
*/
public Object waitAndGet() {
if (obj != null) {
return obj;
}
synchronized (this) {
wait();
return obj;
}
}
}
Вы можете получить null
от waitAndGet()
на самом деле. См. - На самом деле происходит ложное пробуждение?
Ответ 4
Проблема обеда философов - это классический пример concurrency. Эта ссылка имеет одно возможное решение, и многое другое можно найти в Интернете.
Как описано в первой ссылке, этот пример иллюстрирует довольно много общих проблем concurrency. Пожалуйста, пусть ваш профайлер показывает, сколько из них можно отслеживать!
Ответ 5
См. Информационный бюллетень специалистов Java для последовательного потока небольших головоломок Java, многие из которых должны соответствовать вашим потребностям тестирования.
Ответ 6
Я бы рекомендовал оглядеться (или спросить авторов) для набора тестов IBM ConTest, так как он содержит несколько ошибок Java concurrency (к сожалению, не большие программы с открытым исходным кодом). Хорошая вещь в этом тесте состоит в том, что ошибки уже документированы (тип и местоположение).
Если вы хотите найти больше программ, я бы порекомендовал взглянуть на некоторые из исследовательских работ в области тестирования программного обеспечения/качества параллельных программ. Они должны указать образцы программ, которые они использовали в своих исследованиях.
Если все остальное не удается, вы можете попробовать выполнить поиск в GitHub (или аналогичной службе) для репозиториев, содержащих необходимые механизмы concurrency (т.е. синхронизацию). Вы можете найти большое количество Java-кода таким образом, единственная проблема заключается в том, что ошибки не документированы (если вы не ищете исправления фиксации).
Я думаю, что эти три предложения предоставят вам достаточно программ для тестирования вашего профилировщика concurrency.
Ответ 7
Возможно Eclipse или Tomcat развертывание? Ни один из них не очень искусственен, но я мог представить, что вам нужны хорошие инструменты при отладке одного или другого.