2013-08-13 4 views
2

스레드 당 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 당 레코드를 늘리면 프로세스가 오류없이 실행되지만 일괄 처리의 일부만 삽입합니다. 어떤 생각?

+0

코드가 정상적으로 보입니다. DBInsertDetail 인스턴스를 초기화하고 생성하는 vVec을 보여줄 수 있습니까? 나는 당신이'iNum, iCurrSerl, etc'에 문제가 있다고 의심합니다. – Tala

+0

왜 각 쓰레드에서 자고 있습니까? 그게 일종의 시험입니까? 그것은 모든 스레드가'synchronized' 블록을 사용해야하기 때문에 많은 양의 데이터를 삽입하는 유용한 방법처럼 보이지 않습니다. 즉, 병렬 적으로 삽입 할 수없고 결국 순차적으로 실행해야한다는 것을 의미합니다. 그건 이미 하나의 스레드에서만 작동합니다. 또는 모든 스레드를 시작하는 메소드가 스레드가 완료되기 전에 리턴하지 않기 때문에 심지어 0 스레드. – zapl

+0

안녕 Tala & Zalp, 답장을 보내 주셔서 감사합니다. Zalp가 언급했듯이 수면과 동기화 된 블록이 테스트로 추가되었습니다. 처음에는 시도하지 않았지만 실패했습니다. iNum의 경우 iCurrSerl 및 icurtblseq가 올바르게 전달됩니다. 내가 cardcreprocess 메서드에 디버그를 넣고 올바른 값을 반환합니다. pro, prof, getNextNo 메소드로 전달 된 sBranch 값은 정적 변수이지만 모든 것이 공통입니다. – Adambg240

답변

0

이것은 잘못되었습니다. :) 스레드의 일관성으로 인해 그것을 떠날

스레드에서 1000ms 잠. 1 초입니다.

10000 삽입 = 10000 초 = 166 분.

스레드 풀이 15 분 동안 실행되도록 허용 한 다음 종료합니다.

+1

'threadPool.awaitTermination (15, TimeUnit.MINUTES)'는 true 또는 false를 반환합니다. 작업이 중단되지 않습니다. – Tala

+0

죄송합니다. 들여 쓰지 않은 코드가 내게있어 최고가 되겠지. 편집 해 볼게. – Xabster

관련 문제