Негласно, lexical_cast делает это:
std::stringstream str;
str << myint;
std::string result;
str >> result;
, Если Вы не хотите "притягивать" повышение для этого, затем с помощью вышеупомянутого, хорошее решение.
К сожалению, я не верю, что вы можете окончательно доказать, что ваш код является потокобезопасным, используя тестирование во время выполнения. Вы можете бросить столько потоков, сколько захотите, и это может / не может пройти в зависимости от расписания.
Возможно, вам стоит взглянуть на некоторые инструменты статического анализа, такие как PMD , которые могут определить, как вы используете синхронизацию, и выявить проблемы использования.
В вашем примере метод postMessage () синхронизирован , поэтому вы фактически не увидите каких-либо эффектов параллелизма в пределах одной виртуальной машины, но вы сможете оценить производительность синхронизированной версии.
Вам нужно будет запустить несколько копий тестовой программы одновременно на разных виртуальных машинах. Вы можете использовать
. Если вы не можете заставить свою тестовую среду сделать это, вы можете запустить несколько виртуальных машин самостоятельно. Работа с конструктором процессов - это боль с путями и прочим, но вот общий набросок:
Process running[] = new Process[5];
for (int i = 0; i < 5; i++) {
ProcessBuilder b = new ProcessBuilder("java -cp " + getCP() + " MyTestRunner");
running[i] = b.start();
}
for(int i = 0; i < 5; i++) {
running[i].waitFor();
}
Я обычно делаю что-то подобное для простых многопоточных тестов, как и другие, тестирование не является доказательством правильности, но обычно встряхивает устранять глупые ошибки на практике. Это помогает проводить тестирование в течение длительного времени в самых разных условиях - иногда ошибки параллелизма требуют времени, чтобы проявиться в тесте.
public void testMesageBoard() {
final MessageBoard b = new MessageBoard();
int n = 5;
Thread T[] = new Thread[n];
for (int i = 0; i < n; i++) {
T[i] = new Thread(new Runnable() {
public void run() {
for (int j = 0; j < maxIterations; j++) {
Thread.sleep( random.nextInt(50) );
b.postMessage(generateMessage(j));
verifyContent(j); // put some assertions here
}
}
});
PerfTimer.start();
for (Thread t : T) {
t.start();
}
for (Thread t : T) {
t.join();
}
PerfTimer.stop();
log("took: " + PerfTimer.elapsed());
}
}**strong text**
TestNG поддерживает тестирование параллелизма в Java. В этой статье описывается, как его можно использовать, и есть документация на сайте testng.
Не уверен, можно ли выполнить тот же тестовый прогон одновременно
Я бы рекомендовал использовать MultithreadedTC - Написано самим мастером параллелизма Биллом Пью (и Натом Айевах ). тестирование одновременных приложений. Это имеет метроном, который используется для обеспечить точный контроль над последовательностью действий в нескольких потоках.
Эта структура позволяет детерминированно тестировать каждое чередование потоков в отдельных тестах
Вы можете доказать только наличие параллельных ошибок, но не их отсутствие .
Однако вы можете написать специализированное средство запуска тестов, которое порождает несколько параллельных потоков, а затем вызывает ваши аннотированные методы @Test.
В .NET есть такие инструменты, как TypeMock Racer или Microsoft CHESS , которые разработаны специально для параллельного тестирования модулей. Эти инструменты не только находят ошибки многопоточности, такие как взаимоблокировки, но также предоставляют набор чередований потоков, воспроизводящих ошибки.
Я полагаю, что в мире Java есть что-то подобное.
Тестирование ошибок параллелизма невозможно; вам не просто нужно проверять пары ввода / вывода, но вы должны проверять состояние в ситуациях, которые могут или не могут возникнуть во время ваших тестов. К сожалению, JUnit не оборудован для этого.
Лучшим подходом здесь является использование системных тестов, чтобы взорвать ваш код запросами, чтобы увидеть, не упадет ли он. Затем используйте модульный тест, чтобы проверить логическую правильность. Я бы подошел к этому путем создания прокси-сервера для асинхронного вызова и синхронного выполнения его при тестировании.
Однако, если вы хотите сделать это на уровне, отличном от полной установки и полной среды, вы можете сделать это в junit создав свой объект в отдельном потоке, а затем создайте множество потоков, которые запускают запросы к вашему объекту и блокируют основной поток до его завершения. При таком подходе тесты могут периодически выходить из строя, если вы не понимаете его правильно.
Попробуйте найти ActiveTestSuite, который поставляется с JUnit. Он может одновременно запускать несколько тестов JUnit:
public static Test suite()
{
TestSuite suite = new ActiveTestSuite();
suite.addTestSuite(PostMessageTest.class);
suite.addTestSuite(PostMessageTest.class);
suite.addTestSuite(PostMessageTest.class);
suite.addTestSuite(PostMessageTest.class);
suite.addTestSuite(PostMessageTest.class);
return suite;
}
Вышеупомянутый тестовый класс JUnit будет запущен 5 раз в параллельном режиме. Если вам нужны вариации в тестах параллелизма, просто создайте другой класс.
Вы можете использовать библиотеку tempus-fugit для параллельного и многократного запуска тестовых методов для имитации среды типа нагрузочного тестирования. Хотя предыдущий комментарий указывает на то, что метод post синхронизирован и поэтому защищен, могут быть задействованы связанные члены или методы, которые сами по себе не защищены, поэтому возможно, что тест типа load / soak может поймать их. Я бы посоветовал вам настроить довольно грубый / сквозной тест, чтобы дать вам лучший шанс обнаружить любые лазейки.
См. раздел интеграции JUnit в документации.
BTW, я разработчик в указанном проекте :)