본문 바로가기

Java

[Java] Semaphore(세마포어)를 이용한 ThreadExecutor

DB에서 데이터를 읽어와서 네트워크를 통해 뭔가 작업을 한 후

다시 DB에 넣는 작업을 해야하는데 이 데이터의 건수가 많고 네트워크를 통한 작업에 시간이 좀 걸려서

이 부분을 스레드로 돌렸다.


기존에 알고 있는



Executor exec = Executors.newFixedThreadPool(10);


을 사용해서 실행을 했더니 DB에서 데이터 읽어오는 속도가 훨씬 빠른탓에

OOM 에러가 발생하기 시작... 처음에 도무지 왜 에러가 나는지 몰랐는데 확인해보니..

내부에서 스레드들이 처리하지 못 한 JOB을 Queue에 저장해 두는데 이게 너무 쌓이다보니

문제가 되었던듯 하여... 


자바병렬처리 프로그래밍 책을 다시 집어들었다.


미리 준비된 ExecutorService중 스레드가 추가 작업을 하지 못 할 때 

wait을 하는 API는 없다고 하여... 책을 더 뒤적거리고... ..

결국 세마포어를 활용한 BoundedExecutor라는 것이 있어서 이걸 살짝 고쳐서 사용.




다만...

semaphore의 release를 catch에서만 해주고 있어서

Runnable command에서 작업 종료 후 release 해주지 않으면 lock이 발생한다.


책에서는 Semaphore를 생성자에서 생성하도록 되어있는데

이런 경우 어떻게 Runnable command에서 작업 종로 후에 semaphore를 release 해줄 수 있는지

잘 모르겠어서... Semaphore를 외부에서 생성하고 Executor와 Runnable command에게 넘겨주는 방식으로

수정하였다.