A cópia profunda resolve o problema de sobreposição de dados entre threads (registro de prevenção de pit)

introduzir

Existe um requisito tão pequeno:

  • Existem 500 tarefas, primeiro divida essas 500 tarefas em grupos de 50, então um total de 10 grupos podem ser divididos. Em seguida, faça um loop desses 10 grupos de tarefas no pool de threads (atualmente existem 10 grupos de tarefas no pool de threads)
  • O pool de encadeamentos processa esses dez grupos de tarefas separadamente.

O pseudocódigo escrito é o seguinte:

		array = 500个任务;
		JSONArray perThread = new JSONArray();
		int count = 0;
        for(int i = 0; i < 10; i++){
    
    
            //积攒50个一组,攒满了就开一个线程。
            for(50){
    
    
				perThread.add(array.get(count));
				count++;
			}
            
            if (perThread.size() == 50) {
    
    
            	//下面一行代码是启动一个线程池中的线程,执行每一组(50个)任务
                threadPool.submit(()->sendOpenAPI(perThread));
                //清空该组,重新填充。
                perThread.clear(); 
            }
        }

Pense cuidadosamente sobre o que há de errado com o código acima?

analisar problema

Uma referência de objeto (ou seja, a variável perThread) é passada para o thread filho. Quando o thread filho estiver em execução, o thread principal não será bloqueado, mas continuará a ser executado. executar para

perThread.clear()

Nesta linha de código, a referência do objeto (perThread) é limpa. Em seguida, o perThread no segmento filho desaparece. Isso também lida com o cabelo. . . .

solução

Usar uma cópia profunda resolve esse problema. Adapte esse bloco de código da seguinte forma:

				if (perThread.size() == 50) {
    
    
				//开新线程。
                JSONArray deepCopy = new JSONArray();   //对原来的对象进行深拷贝。
                BeanUtils.copyProperties(perThread,deepCopy);
                threadPool.submit(()->sendOpenAPI(deepCopy));

                perThread.clear();  //放心清空即可,反正已经将深拷贝后的东西传入子线程了
                
                }

Usando cópia profunda, uma nova referência de objeto é usada no thread filho. Mesmo que a referência de objeto original seja esvaziada no thread principal, o objeto não será esvaziado porque há um novo espaço de memória no thread filho.

problema resolvido.

Acho que você gosta

Origin blog.csdn.net/weixin_44757863/article/details/122378799
Recomendado
Clasificación