深拷贝解决线程间数据互相覆盖问题(避坑记录)

引入

有这样一个小需求:

  • 有500个任务,先将这500个任务按照50个一组进行切分,那么一共可以切分成10组。然后循环将这10组任务传入线程池(现在的线程池里共有10组任务)
  • 线程池将这十组任务分别处理。

写出来的伪代码如下:

		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(); 
            }
        }

仔细思考一下上面这段代码有什么问题?

分析问题

一个对象引用(也就是perThread这个变量),被传入了子线程中。而子线程运行的时候主线程不会阻塞,而是继续执行。执行到

perThread.clear()

这行代码的时候,该对象引用(perThread)就被清空了。那么子线程里面的 perThread 也没了。这还处理个毛。。。。

解决方案

使用深拷贝可解决此问题。将那块代码改编如下:

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

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

利用深拷贝,子线程中使用了新的对象引用,即使主线程中将原对象引用清空,由于已经子线程里是个全新的内存空间,所以对象不会被清空。

问题解决。

猜你喜欢

转载自blog.csdn.net/weixin_44757863/article/details/122378799