ディープコピーは、スレッド間でデータが重複する問題を解決します(ピット回避レコード)

導入

そのような小さな要件があります:

  • 500のタスクがあり、最初にこれらの500のタスクを50のグループに分割し、次に合計10のグループを分割できます。次に、これらの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