Подтвердить что ты не робот

Как я могу эффективно тестировать (единицу/интеграцию) параллельный код в Java?

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

4b9b3361

Ответ 1

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

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

Ответ 2

Я обычно генерировал огромное количество (например, 100) потоков в unit test и отправил их против него в надежде попасть в состояние гонки:). К сожалению, это не очень однозначно. Вы можете улучшить свои шансы, хотя, имея отладочные строки в областях, чувствительных к потоку, которые заставляют активный поток спать за X миллис. Эта стратегия позволяет вам оставлять зияющие окна, где другие потоки могут чередовать. Эти строки будут активны только во время модульного тестирования (используйте аспекты или строки жесткого кода, которые активируются только при установке флага отладки).

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

Ответ 3

Я предлагаю вам получить Java Concurrency на практике - это не только говорит вам, как избежать условий гонки в первую очередь, есть раздел по тестированию concurrency.

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

Ответ 4

Один хороший способ проверить это - убедиться, что у вас есть доступ к компьютеру с несколькими процессорами, а затем запустить тест как можно дольше/с максимально возможным количеством итераций. Например, если у вас есть многопоточный алгоритм потребительского производителя, заполните очередь с хорошим размером списка и используйте 2x столько потоков, сколько вы могли бы произвести. Это должно по крайней мере дать вам шанс чаще всего столкнуться с состоянием гонки или проблемой синхронизации. Затем запустите этот тест в ежедневной сборке.

Ответ 5

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

В конечном счете, нет пути по методу чисел unit test MT, чтобы убедиться, что он не уязвим для состояния гонки.

Ответ 6

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

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