本文主要介紹多線程操作字符串必須使用stringbuffer(java多線程并行處理數(shù)據(jù)丟失),下面一起看看多線程操作字符串必須使用stringbuffer(java多線程并行處理數(shù)據(jù)丟失)相關(guān)資訊。
需求:
數(shù)據(jù)會從第三方拉過來存儲在表中,表中字段太多(150個(gè)字段),需要滿存儲。
方法:
對數(shù)據(jù)存儲使用多線程來加速存儲。
遇到的問題:
因?yàn)閿?shù)據(jù)量很大,一個(gè)頁面可以查找5000條數(shù)據(jù),每條數(shù)據(jù)有150個(gè)字段,所以得到的字符串會很長,然后因?yàn)榇鎯υ谝粋€(gè)字符串中,所以當(dāng)前的string對象會很大。
因?yàn)閖vm算法的原因,新一代的垃圾回收采用了復(fù)制算法,復(fù)制算法的缺點(diǎn)是當(dāng)大量大對象存在時(shí),回收效率會降低。由于需要復(fù)制移動(dòng)對象,新一代采用大對象直接進(jìn)入舊時(shí)代來避免這個(gè)缺點(diǎn),避免大對象在新一代中存活時(shí)間過長,影響gc效率。通過-xx:perenuresizethreshold的參數(shù)配置,單位大小為字節(jié),如-xx:perenuresizethreshold = 1024,表示垃圾回收時(shí)大小超過1kb的對象直接進(jìn)入老年。
因?yàn)閟tring對象的數(shù)據(jù)量太大,超過了默認(rèn)值1kb,所以在堆空間進(jìn)行g(shù)c的時(shí)候會被放入舊時(shí)代,無法重用string對象的特性。每次賦值時(shí),都會創(chuàng)建一個(gè)新的string對象。此時(shí),當(dāng)數(shù)據(jù)量超過一定數(shù)量級(我的數(shù)據(jù)量在23萬左右)時(shí),堆內(nèi)存就會出現(xiàn)內(nèi)存溢出:java堆空間錯(cuò)誤,或者java lang內(nèi)存不足錯(cuò)誤:垃圾回收gc * * *錯(cuò)誤。
解決方案:
首先我們需要把新threadpoolexecutor的創(chuàng)建放在循環(huán)之外,然后盡量少用string來接收循環(huán)中的大量級別數(shù)據(jù),改用stringbuffer或者stringbuilder。如果我們別無選擇,只能使用string接收大量的level數(shù)據(jù),就需要在進(jìn)入下一個(gè)循環(huán)之前清空數(shù)據(jù)(string = null),從而提示gc回收這個(gè)對象。
//創(chuàng)建新的線程池執(zhí)行器service executor =新的線程池執(zhí)行器(5,20,0,timeunit。秒,//1。如果使用無界隊(duì)列,大量提交的任務(wù)會堆積起來,造成內(nèi)存占用高//newlink。dblockingqueuerunnable,//2。應(yīng)該使用有界隊(duì)列newlinkedblockingqueuerunnable(50),//2。添加調(diào)用線程任務(wù)本身來運(yùn)行newthreadpool executor。callerrunpolicy);list future future list = new arraylist;oeresulttlycarinfo oe result = new oe result;字符串?dāng)?shù)據(jù)= count = ins: future list){ try { future . get;} catch(exception e){ system . out . println(e);} } private int insert data(mapstring,object params,string url,string pageindex,int num,executorservice executor,listfuture futurelist,oeresulttlycarinfo oeresult,java . lang . string post){ params . put( 頁面索引 ,page index);post = http utils . post(params,url);oeresult = jsonutil.tobean(post,new typereferenceoeresulttlycarinfo{ },false);listtlycarinfo oed atalist = oe result . get result;post = nullnum = o datalist . size;//剪切列表listlisttlycarinfo partition = lists。分區(qū)(oe數(shù)據(jù)表,500);//多線程執(zhí)行保存任務(wù)//partition.stream。地圖(子公司mpletablefuture . supplyasync(-tlycarinfoservice . save batch(sub),executor))。collect(collectors . to list);for(listlycarinfo tlycarinfos :分區(qū)){ future future = executor . submit(new runnable{ @ override public void run{ try { tlycarinfoservice . save batch(tlycarinfos,1000));} catch(exception e){ system . out . println(e);} } });futurelist.add(未來);}如果(!oeresult.getinfo。getsdmpageindex。等于( -1 )){ system . out . println( sdmpageindex = = = = = = = = = = = oeresult.getinfo。getsdmpageindex);//當(dāng)sdmpageindex不為-1時(shí),有后續(xù)頁面,需要繼續(xù)存儲insertdata (params,url,oeresult。getinfo。getsdmpageindex,num,executor,futurelist,oeresult,post);}返回num}這是個(gè)人用的。如果描述有誤,請指正。
標(biāo)簽:
對象數(shù)據(jù)
了解更多多線程操作字符串必須使用stringbuffer(java多線程并行處理數(shù)據(jù)丟失)相關(guān)內(nèi)容請關(guān)注本站點(diǎn)。