스레드 당 10 개의 스레드를 사용하여 50000 개의 레코드를 데이터베이스에 삽입해야합니다. Ex. 스레드 1은 1-5000을 삽입하고 스레드 2는 5001-10000을 삽입합니다.스레드 실행이 루프에서 완료되지 않았습니다.
이 작업을 수행하려면 ExecutorService를 사용해야합니다.
코드
ExecutorService threadPool = Executors.newFixedThreadPool(10);
int i=0;
while(i<vVec.size())
{
if(i<vVec.size())
{
DBInsertDetail rrr = (DBInsertDetail)vVec.get(i);
TestThread t1 = new TestThread(rrr);
threadPool.execute(t1);
}
i++;
}
try {
threadPool.shutdown();
boolean bTermination = false;
while (true)
{
bTermination = threadPool.awaitTermination(15, TimeUnit.MINUTES);
if(!bTermination)
{
Log.debug("Awaiting completion of threads.");
}
else
{
Log.debug("Threads Completed."+iTermiVal);
break;
}
if(threadPool.isTerminated())
{
break;
}
}
} catch (Exception e) {}
TestThread 클래스
public class TestThread implements Runnable
{
private volatile DBInsertDetail syncc;
public Thread1(DBInsertDetail syncc) {
this.syncc = syncc;
}
public void run() {
try
{ this.syncc.cardCreProcess(syncc.getIncre(),syncc.getStarterial(),syncc.getCurTblSeq());
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
DBInsertDetail 클래스
public class DBInsertDetail {
public void cardCreProcess(int iNum,int iCurrSerl,int iCurTblSeq)
{
int iCardCountTest = 0;
try
{
synchronized(this)
{
for (int i = 0; i < iNum; i++)
{
iCurrSerl++;
iCurTblSeq++;
iCardCountTest++;
CmnDet stkDet = new CmnDet();
Data crdData = new Data();
String sNo = crdData.getNextNo(pro, prof, sBranch, iCurrSerl);
stkDet.setNo(sNo);
stkDet.setCod(""+iCurTblSeq);
if (!stkDet.saveToDataBase(con))
{
sErrorMsg +="Error Occured" + "\n";
}
}
}
}catch(Exception ex)
{
ex.printStackTrace();
}
finally{
//commit and return connection
}
}
}
문제는이 큰 번호에 대해 올바르게 실행되지 않습니다이다. 스레드 10000 당 레코드를 늘리면 프로세스가 오류없이 실행되지만 일괄 처리의 일부만 삽입합니다. 어떤 생각?
코드가 정상적으로 보입니다. DBInsertDetail 인스턴스를 초기화하고 생성하는 vVec을 보여줄 수 있습니까? 나는 당신이'iNum, iCurrSerl, etc'에 문제가 있다고 의심합니다. – Tala
왜 각 쓰레드에서 자고 있습니까? 그게 일종의 시험입니까? 그것은 모든 스레드가'synchronized' 블록을 사용해야하기 때문에 많은 양의 데이터를 삽입하는 유용한 방법처럼 보이지 않습니다. 즉, 병렬 적으로 삽입 할 수없고 결국 순차적으로 실행해야한다는 것을 의미합니다. 그건 이미 하나의 스레드에서만 작동합니다. 또는 모든 스레드를 시작하는 메소드가 스레드가 완료되기 전에 리턴하지 않기 때문에 심지어 0 스레드. – zapl
안녕 Tala & Zalp, 답장을 보내 주셔서 감사합니다. Zalp가 언급했듯이 수면과 동기화 된 블록이 테스트로 추가되었습니다. 처음에는 시도하지 않았지만 실패했습니다. iNum의 경우 iCurrSerl 및 icurtblseq가 올바르게 전달됩니다. 내가 cardcreprocess 메서드에 디버그를 넣고 올바른 값을 반환합니다. pro, prof, getNextNo 메소드로 전달 된 sBranch 값은 정적 변수이지만 모든 것이 공통입니다. – Adambg240