2013-09-25 4 views
0

사용자가 작업을 생성하기 위해 일부 데이터를 받아들이는 웹 응용 프로그램이 있으며 작업이 실행되어야합니다.자바 스레드 대기 및 자동 시작

작업을 실행하면 인터넷에서 무언가를 다운로드하는 데 시간이 걸리므로 작업을 수행 할 새 스레드를 만들려고했습니다.

이 내 생각이다 :

  1. 만들고 데이터를 다운로드하는 데 사용되는 LoaderThread. 그리고 LoaderThreadTask에 사용 된 ArrayList 필드를 보유합니다.

  2. Servlet 요청 및 응답을 처리합니다. Servlet 시작, 서블릿을 실행하는 동안 LoaderThread

  3. 을 시작 LoaderThread에 작업을 추가

  4. .

코드 (그들 중 일부 생략)이다

public class RwdServlet extends HttpServlet { 
    private StaticMapLoader loader; 

    @Override 
    public void init() throws ServletException { 
     super.init(); 

     loader = new StaticMapLoader(); 
     loader.startRunning(); 
    } 
    @Override 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
     Task t=createTask(req); 
     loader.addTask(t); 
    } 
    @Override 
    public void destroy() { 
     loader.stopRunning(); 
    } 
} 


public class StaticMapLoader extends Thread { 
    private List<Task> tasks = new ArrayList<Task>(); 
    private boolean running = false; 

    @Override 
    public void run() { 
     while (running) { 
      if (tasks.size() > 0) { 
       Task t = tasks.get(0); 
       log.info(t); 
       if (t != null && t.status == Status.waiting) { 
        tasks.remove(0); 
        t.status = Status.running; 
        downLoad(t); 
       } 
      } 
     } 
    } 

    private void downLoad(Task t) { 
     //download file 
    } 

    public void addTask(Task t) { 
     tasks.add(t); 
    } 

    public void startRunning() { 
     running = true; 
     this.start(); 
    } 

    public void stopRunning() { 
     running = false; 
     this.interrupt(); 
    } 
} 

위의 코드는 작동했지만 나는 심지어 tasks이 비어있는 것을 발견하고, 새로운 task이 추가되지 루프가 계속 달릴거야.

그렇다면 아무런 작업이 없을 때 잠깐 중단하고 새로운 작업이 나올 때 알려 주면됩니다.

@Override 
public void run() { 
    while (running) { 
     if (tasks.size() > 0) { 
      Task t = tasks.get(0); 
      log.info(t); 
      if (t != null && t.status == Status.waiting) { 
       tasks.remove(0); 
       t.status = Status.running; 
       downLoad(t); 
      } 
     } else { 
      try { 
       wait(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

     } 
    } 
} 

나는 tasks가 비어있는 경우 wait() 전화를 시도 :

그래서 나는이 시도.

하지만 어떻게 깨우는 지 모르겠습니까?

또한 애플리케이션을 개선하기 위해 알아야 할 것이 있습니까?

BWT, 둘 이상의 LoaderThread 인스턴스가 만들어 질 수 있습니까? 그렇다면 어떻게 피하는가?


내가 다른 구현을 사용할 수있는 것 같다,하지만 내 경우 리팩터링-수 있을까?

내가 놓친 몇 가지 사실을 배우고 싶습니다. :) 감사.

답변

2

귀하의 요구 사항은 ExecutorService의 표준 사용법이므로 ExecutorService을 사용하고 휠을 재발행하지 않을 것을 권장합니다.

귀하가 제공 한 코드에 대한 자료, 서블릿은 다음과 같아야합니다

public class RwdServlet extends HttpServlet { 
    private ExecutorService loader; 

    @Override 
    public void init() throws ServletException { 
     super.init(); 
     loader = Executors.newCachedThreadPool();//or use some other executor, google about difference between them 
    } 
    @Override 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
     Task t=createTask(req); //assume that task implements Runnable or Callable 
     loader.submit(t); // submit a task to executor after this line your task will start execution in another thread 
    } 
    @Override 
    public void destroy() { 
     loader.shutdown();//this will destroy executor service but before that it will wait until all already submitted tasks will be executed 

    } 
} 

link with example

+0

'ExecutorService'가 (가) 자동으로 대기 및 종료 할 수 있습니까? – hguser

+0

자동으로 일어나서 무엇을 의미합니까? 초기화 할 때와 대기 모드에서'ExecutorService' 작업을 제출하기 전에. 작업을 제출하면 비동기 적으로 계산이 시작됩니다. – nkukhar

+0

모든 작업은 끝났습니다. 'ExecutorService'는 다시 "대기"상태가되고 잠시 후 새 작업이 작업에 추가되면 시작됩니까? – hguser

0

사용 사례가 ExecutorService를 요구하고 처음부터 다시 구현 시작을 참조하십시오. 이제는 더 이상 멈추지 말고 표준 라이브러리에서 완성 된 버그없는, 유연하고 강력한 제품을 사용하십시오.

+0

을 사용하여 내 대답을 편집했습니다. 죄송 합니다만, 귀하의 의미가 확실하지 않습니다. 당신은'ExecutorService'를 사용하도록 권하겠습니까? – hguser

+0

@hguser : 이미 존재하는 것을 만들려고한다는 것을 의미하므로 시간 낭비를 줄이고 더 나은 라이브러리를 사용해야합니다. 당신이 놀라운 기술을 가지고 있지 않다면, 당신의 결과는 이미 존재하는 것보다 좋지 않을 것입니다. :) – Izmaki

+0

@lzmaki : 고마워, 알았다. – hguser