2013-05-20 2 views
1

사이트에 대한 HTTP 요청을 작성한 후 응답을 검색하고 검사 한 다음 특정 키워드를 포함하는 경우 HTTP 요청 및 응답을 XML 파일에 모두 쓰는 응용 프로그램이 있습니다. . 이 응용 프로그램은 스파이더를 사용하여 사이트의 모든 URL을 매핑 한 다음 요청을 보냅니다 (사이트 맵의 각 URL은 요청을 보내는 별도의 스레드로 전달됩니다). 이렇게하면 모든 요청이 언제 전송되었는지 알 수 없게됩니다. 내가 XML 파일을 다른 형식으로 변환하기를 원한다. 따라서 요청이 끝났을 때 다음 전략을 사용합니다.특정 조건이 스레드에서 참이 될 때까지 대기

각 요청 시간을 변수에 저장합니다 (새 요청이 변수의 시간보다 늦은 시간에 전송되면 varible이 업데이트 됨). 또한이 시간을 모니터링하는 스레드를 시작하고 현재 시간과 가변 시간의 차이가 1 분 이상이라면 요청 전송이 중지되었음을 알 수 있습니다. 이러한 목적으로 다음 코드를 사용합니다.

class monitorReq implements Runnable{ 
    Thread t; 
    monitorReq(){ 
     t=new Thread(this); 
     t.start(); 
    } 
    public void run(){ 
     while((new Date().getTime()-last_request.getTime()<60000)){ 
      try{ 
       Thread.sleep(30000);//Sleep for 30 secs before checking again 
      } 
      catch(IOException e){ 
       e.printStackTrace(); 
      } 
     } 
     System.out.println("Last request happened 1 min ago at : "+last_request.toString()); 
     //call method for conversion of file 
    } 
} 

이 방법이 맞습니까? 아니면 같은 것을 구현할 수있는 더 좋은 방법이 있습니까?

답변

1

현재 접근 방식은 신뢰할 수 없습니다. 경쟁 조건에 도달하게됩니다 - 스레드가 시간을 업데이트하는 경우 & 다른 스레드가 동시에이를 읽습니다. 또한 여러 스레드에서 요청 처리를 수행하는 것이 어려울 것입니다. 당신은 그 작업이 60 초 내에 완료된다고 가정하고 있습니다.

다음은 더 나은 접근 방법입니다.

당신은 당신이 손 전에 요청의 수를 알 수없는 경우 당신은 당신이 수행 할 수있는 ExecutorService입니다을 사용할 수있는 CountDownLatch를

main() { 
    int noOfRequests = ..; 
    final CountDownLatch doneSignal = new CountDownLatch(noOfRequests); 

    // spawn threads or use an executor service to perform the downloads 
    for(int i = 0;i<noOfRequests;i++) { 
     new Thread(new Runnable() { 
     public void run() { 
      // perform the download 
      doneSignal.countDown(); 
     } 
     }).start(); 
    } 

    doneSignal.await(); // This will block till all threads are done. 
} 

을 사용할 수 있습니다 손 전에 만들려고하는 요청의 수를 알고있는 경우 스레드 풀을 사용하여 다운로드/처리

주() {

ExecutorService executor = Executors.newCachedThreadPool(); 
    while(moreRequests) { 
    executor.execute(new Runnable() { 
     public void run() { 
     // perform processing 
     } 
    }); 
    } 

    // finished submitting all requests for processing. Wait for completion 
    executor.shutDown(); 
    executor.awaitTermination(Long.MAX_VALUE, TimeUnit.Seconds); 

}

+0

보내질 요청은 알 수 없습니다. – Rishabh

+0

이 다른 접근 방식으로 답변을 업데이트했습니다. – gkamal

0

일반적인 사항 : 자바에서

  1. 클래스는 대문자로 시작해야

    당신의 스레드 사이에 동기화 할 수없는 것 같다
  2. ; last_request에 대한 접근은 아마도 이것이 좋은 방법이 아닙니다처럼 예외를 삼키는 당신에게 객체의 생성 오버 헤드

  3. 을 절약 할 수 System.currentTimeMillis()를 사용

  4. 을 동기화해야

답변 :

당신이 그것을하는 당신의 방법은 허용됩니다. 기다리는 데별로 바쁘지 않고 생각만큼 간단합니다. 어느 것이 좋니.

대기 시간을 더 낮은 값으로 변경하는 것이 좋습니다. 데이터가 너무 적어 매 초마다이 루프를 수행해도 처리 능력이 떨어지지 않고 앱의 반응 시간이 향상됩니다.

관련 문제