Java多线程不更新单元测试中的值
我有一个Spring服务,我想测试它对并发线程的正确性Java多线程不更新单元测试中的值,java,spring,multithreading,unit-testing,Java,Spring,Multithreading,Unit Testing,我有一个Spring服务,我想测试它对并发线程的正确性 @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest public class SerialNumberServiceTest { @Autowired private SerialNumberService service; private final static int NUM_THREADS = 10; private final static int NUM_ITERA
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class SerialNumberServiceTest {
@Autowired
private SerialNumberService service;
private final static int NUM_THREADS = 10;
private final static int NUM_ITERATIONS = 100;
@Test
public void testSynchronized(){
ExecutorService executor = Executors.newFixedThreadPool(10);
final Set<String> result = new HashSet<String>();
int size = 0;
for(int i = 0; i < NUM_THREADS; i++){
executor.submit(new Runnable() {
@Override
public void run() {
for (int j = 0; j < NUM_ITERATIONS; j++) {
String code = service.generateSerialNumberByModelCode("LP");
result.add(code);
}
}
});
}
assertEquals(NUM_ITERATIONS * NUM_THREADS, result.size());
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@春靴测试
公共类SerialNumberService测试{
@自动连线
私人SerialNumberService服务;
私有最终静态int NUM_线程=10;
私有最终静态int NUM_迭代=100;
@试验
公共void testSynchronized(){
ExecutorService executor=Executors.newFixedThreadPool(10);
最终设置结果=新的HashSet();
int size=0;
对于(inti=0;i
我想断言生成了多少代码,并检查是否有重复的代码。
但是结果集为空。我不知道为什么
另一方面,如果我尝试更新线程中服务实例的值,我也会发现这些值没有保存。e、 g
public void run() {
for (int j = 0; j < NUM_ITERATIONS; j++) {
String code = service.generateSerialNumberByModelCode("LP");
service.incrValue();
result.add(code);
}
}
public void run(){
对于(int j=0;j
最后,service.getValue()是不变的
有人能给我解释一下吗?这个代码有很多错误 1) 您正在使用一个
HashSet
并在多个线程中更新它,但是HashSet
被记录为非线程安全。这将导致意外行为,或者如果幸运的话,您将遇到ConcurrentModificationException
。将其打包成一个同步集
2) 在执行断言之前,您不会等待提交的线程完成。使用
invokeAll
启动多个线程,或者通过在执行器上执行shutdown
,然后等待终止来等待所有线程完成。要获得更好的解释,请参阅以下问题:此代码有很多错误
1) 您正在使用一个HashSet
并在多个线程中更新它,但是HashSet
被记录为非线程安全。这将导致意外行为,或者如果幸运的话,您将遇到ConcurrentModificationException
。将其打包成一个同步集
2) 在执行断言之前,您不会等待提交的线程完成。使用
invokeAll
启动多个线程,或者通过在执行器上执行shutdown
,然后等待终止来等待所有线程完成。有关更好的解释,请参见此问题:是否存在输出字符串与已添加到哈希集的字符串冲突的情况?在本例中,代码字符串只是在hashset上被覆盖。我想说的是,hashset中的每个代码字符串值都应该是唯一的。您还可以减少迭代次数以更好地调试…是否存在输出字符串与已添加到hashset的字符串冲突的情况?在本例中,代码字符串只是在hashset上被覆盖。我想说的是,hashset中的每个代码字符串值都应该是唯一的。您还可以减少迭代次数以更好地调试…谢谢@john16384,我将设置更改为ConcurrentHashMap,并添加executor.awaitTermination(5,TimeUnit.SECONDS)。这样可以吗?这样做的可能性会大得多。再测试一下,看看它现在是否如您所期望的那样工作。不要忘记在等待终止之前调用shutdown
。谢谢@john16384,我将设置更改为ConcurrentHashMap,并添加了executor.awaitTermination(5,TimeUnit.SECONDS)。这样可以吗?这样做的可能性会大得多。再测试一下,看看它现在是否如您所期望的那样工作。在等待终止之前,不要忘记调用shutdown
。