Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Сегодня все большую популярность приобретает.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
270.85 Кб
Скачать

Многопоточность

Нужно проверить, как поведет себя приложение во многопоточном окружении? Можно сделать так, чтобы тесты исполнялись одновременно из нескольких потоков:

public class ConcurrencyTest extends Assert {

private Map<String, String> data;

@BeforeClass

void setUp() throws Exception {

data = new HashMap<String, String>();

}

@AfterClass

void tearDown() throws Exception {

data = null;

}

@Test(threadPoolSize = 30, invocationCount = 100, invocationTimeOut = 10000)

public void testMapOperations() throws Exception {

data.put("1", "111");

data.put("2", "111");

data.put("3", "111");

data.put("4", "111");

data.put("5", "111");

data.put("6", "111");

data.put("7", "111");

for (Map.Entry<String, String> entry : data.entrySet()) {

System.out.println(entry);

}

data.clear();

}

@Test(singleThreaded = true, invocationCount = 100, invocationTimeOut = 10000)

public void testMapOperationsSafe() throws Exception {

data.put("1", "111");

data.put("2", "111");

data.put("3", "111");

data.put("4", "111");

data.put("5", "111");

data.put("6", "111");

data.put("7", "111");

for (Map.Entry<String, String> entry : data.entrySet()) {

System.out.println(entry);

}

data.clear();

}

}

  • threadPoolSize определяет максимальное количество потоков используемое для тестов.

  • singleThreaded если установлен в true все тесты будут запущены в одном потоке.

  • invocationCount определяет количество запусков теста.

  • invocationTimeOut определяет общее время всех запусков теста, после которого тест считается провалившемся.

Первый тест будет время от времени проваливаться с ConcurrentModificationException, так как будет запускаться из разных потоков, второй — нет, так как все тесты будут запущены последовательно из одного потока. Еще можно установить параметр parallel у дата провайдера в true, тогда тесты для каждого набора данных будут запущены паралельно, в отдельном потоке:

public class ConcurrencyTest extends Assert {

// some staff here

@DataProvider(parallel = true)

public Object[][] concurrencyData() {

return new Object[][] {

{"1", "2"},

{"3", "4"},

{"5", "6"},

{"7", "8"},

{"9", "10"},

{"11", "12"},

{"13", "14"},

{"15", "16"},

{"17", "18"},

{"19", "20"},

};

}

@Test(dataProvider = "concurrencyData")

public void testParallelData(String first, String second) {

final Thread thread = Thread.currentThread();

System.out.printf("#%d %s: %s : %s", thread.getId(), thread.getName(), first, second);

System.out.println();

}

}

Данный тест будет выводить нечто вроде:

#16 pool-1-thread-3: 5 : 6

#19 pool-1-thread-6: 11 : 12

#14 pool-1-thread-1: 1 : 2

#22 pool-1-thread-9: 17 : 18

#20 pool-1-thread-7: 13 : 14

#18 pool-1-thread-5: 9 : 10

#15 pool-1-thread-2: 3 : 4

#17 pool-1-thread-4: 7 : 8

#21 pool-1-thread-8: 15 : 16

#23 pool-1-thread-10: 19 : 20

Без этого параметра будет что-то вроде:

#1 main: 1 : 2

#1 main: 3 : 4

#1 main: 5 : 6

#1 main: 7 : 8

#1 main: 9 : 10

#1 main: 11 : 12

#1 main: 13 : 14

#1 main: 15 : 16

#1 main: 17 : 18

#1 main: 19 : 20