最近在工作中需要將一大批資料匯入到資料庫中,因為種種原因這些資料不能使用同步資料的方式來進行複製,而是提供了一批文字,文字裡面有很多行url位址,需要的字段都包含在這些url中。最開始是使用的正常的普通方式去寫入,但是量太大了,所以就嘗試使用多執行緒來寫入。下面我們就來介紹一下怎麼使用多執行緒進行匯入。
格式就是類似於這種格式的url,當然這裡只是舉個例子,大概有300多個文字,每個文字裡面有大概25000條url,而每條url要插入兩個表,這個量還是有點大的,單執行緒跑的非常慢。
我們需要建立乙個executorconfig
類來設定執行緒池的各種配置。
我們需要建立乙個介面,再這個介面裡面宣告了我們需要呼叫的非同步方法@configuration
@enableasync
public class executorconfig
}
public inte***ce asyncservice
@service
public class asyncserviceimpl implements asyncservice catch (ioexception e)
});}catch (exception e)
}}
上面的步驟已經基本實現了多執行緒的操作,但是當我真的開始匯入資料的時候又發現乙個問題,就是每次執行後才剛開始匯入就自動停止了,原因是我在junit中執行了**後它雖然開始匯入了,但是因為資料很多時間很長,而juint跑完主線程的邏輯後就把整個jvm都關掉了,所以匯入了一點點就停止了,上面的測試方法之所以沒問題是因為幾個檔案的複製速度很快,在主線程跑完之前就跑完了,所以看上去沒問題。最開始我用了乙個最笨的方法,直接在主線程最後呼叫@runwith(springrunner.class)
@springboottest
@autowired
private asyncservice asyncservice;
@test
public void write() catch (ioexception e)
}
thread.sleep()
方法,雖然有效果但是這也太low了,而且你也沒法判斷到底資料導完沒有。所以我又換了乙個方式。
countdownlatch是乙個同步工具類,它允許乙個或多個執行緒一直等待,直到其他執行緒執行完後再執行。它可以使主線程一直等到所有的子執行緒執行完之後再執行。我們修改下**,建立乙個countdownlatch例項,大小是所有執行執行緒的數量,然後在非同步類的方法中的finally裡面對它進行減1,在主線程最後呼叫await()
方法,這樣就能確保所有的子執行緒執行完後主執行緒才會繼續執行。
@runwith(springrunner.class)
@springboottest
private final countdownlatch countdownlatch = new countdownlatch(10);
@autowired
private asyncservice asyncservice;
@test
public void mainwait()
countdownlatch.await();
} catch (interruptedexception e)
}}
雖然上面的多執行緒是重點,不過還是把匯入資料的**展示出來給大家參考一下,當然這是簡化版,真實的要比這個多了很多判斷,不過那都是基於業務需求做的判斷。@service
public class asyncserviceimpl implements asyncservice
}system.out.println("執行緒" + thread.currentthread().getid() + "執行結束");
} catch (exception e) finally
}}
@runwith(value = springrunner.class)
@springboottest
private final countdownlatch countdownlatch;
@autowired
asyncservice asyncservice;
@test
public void writecode() );
countdownlatch.await();
catch (interruptedexception e)
}}
@service
public class asyncserviceimpl implements asyncservice
return "匯入完成-" + filename;
}catch (exception e)finally
}}
springBoot執行緒池
1 定義執行緒池 enableasync configuration classtaskpoolconfig 上面我們通過使用threadpooltaskexecutor建立了乙個執行緒池,同時設定了以下這些引數 說明 setwaitfortaskstocompleteonshutdown true...
Springboot 執行緒池
配置類 configuration enableasync public class taskpoolconfig 執行執行緒中,如果有區域性變數要使用 或者有外部值傳入 新建thead 實現callable介面 可以直接使用函式中的值的話使用lambda表示式,使用completionservic...
springboot 執行緒池
1 在啟動類上加標記 enableasync slf4j exclude enableasync public class extends springbootservletinitializer 3 使用,方法名上加 async asyncserviceexecutor 這個方法只在外部呼叫才會開...