SW-PRODUCT/개발

Executors.newFixedThreadPool(nSize)

굴돌 2014. 1. 9. 20:48


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