ThreadPoolExecutor
- Unbounded queue(예: LinkedBlockingQueue를 capacity 없이 생성)를 사용할 경우 corePoolSize 갯수의 Worker가 작업중이면 queue에 들어간다. 즉, corePoolSize 이상으로 커지지 않는다.
- Worker가 corePoolSize보다 많이 있을 경우 queue.poll()할 때 keepAlive만큼만 기다리고, corePoolSize보다 같거나 작을 경우 무작정 기다린다.
- shutdown()이 호출되면 SHUTDOWN 상태로 바꾼 후, 모든 worker에 대해서 idle인 것은 interrupt 건다.
-- worker는 interrupt 걸렸을 경우 상태를 체크해서 STOP/TERMINATE이면 바로 종료하고, SHUTDOWN이면 queue에서 하나 더 꺼내서 처리하고, 없으면 종료할 수 있는지 체크해서 가능하면 종료하고(이때, 모든 worker를 깨운다.) 이 작업을 한번 더 돈다.
-- 결국, 어지간하면 queue에 있는것들은 다 처리한다.
- Executors.newFixedThreadPool(nSize)를 사용하면 nSize보다 많은 요청이 몰릴 경우 자신의 queue에 담아뒀다가 worker가 한가해지면 처리한다.
-- 이거면 굳이 redis queue를 쓸 필요도 없었나? =.=;;;
-- 그나마 폭주해도 톰캣 밖에 안전한 곳에 저장해둔다는 의미정도였는데... 처리 못하는것들도 Executor가 다 들고와버리는 바람에 그런 의미도 퇴색됐다.
Redis에서 nSize 만큼만 가져와서 처리하고,
worker가 모두 작업중일때는 더이상 가져오지 않고 기다리도록 하려면...
그나마 가장 가까운건
ThreadPoolExecutor ex = new ThreadPoolExecutor( POOL_SIZE, POOL_SIZE, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(POOL_SIZE), new ThreadPoolExecutor.CallerRunsPolicy() );
이렇게 선언해서 queue 크기를 고정시키고,
pool이 꽉찬 상태에서 ex.execute()가 호출되면
CallerRunsPolicy()에 따라서 ConsumeManager가 처리하도록 한다.
...
그런데 이럴 경우 처리 중에 exception 발생하면 Manager 자체가 죽어버려서 문제인데..;;
execute()에서 넣을 수 있을때까지 기다리는게 있으면 좋을텐데 =.=;;
아니면 AbortPolicy를 적용해서
RejectedExecutionException 던져졌을 때
일정시간 대기 후에 다시 execute()를 호출하는 형태로 하면 될 듯!!
이게 좋겠다..
...
그나마도 queue 크기를 1로 하면 순간적으로 1개는 대기할 수 있기 때문에
작업 한개는 물고 죽을 수는 있다...
뭐 이정도는 pass..;;
'SW-PRODUCT > 개발' 카테고리의 다른 글
Java에서 Seriazable한 객체 replication.. (0) | 2014.06.11 |
---|---|
쿠키런 서버 사례: NoSQL + AWS AutoScale (0) | 2014.06.05 |
멀티쓰래드 Lock-free, C++, CAS from NDC (0) | 2014.06.02 |
Tech Resources (0) | 2013.11.19 |
MySQL Tips... (0) | 2013.11.13 |