본문 바로가기

JAVA

JAVA(2022.06.03) - 메소드 동기화

- 멀티 쓰레드 환경에서 여러 쓰레드가 동시에  변수에 접근하는 것을  막기 위해 메소드 동기화(Synchronization)를 사용

- 쓰레드의 실행순서를 지정해야 할 때도 사용 

 

방법 

 

- 메소드 앞에 synchronized를 붙인다

- 메소드에 synchronized가 붙어있으면, 먼저 호출된 메소드가 monitoring Lock을 얻는다 

- monitoring Lock을 얻은 메소드는 wait()를 만나거나 실행이 종료될 때 까지 우선권을 얻고 계속 출력된다 

- 동기화 되지 않은 메소드들은  synchronized메소드들이 실행되더라도 관계없이 실행된다 

- 대기시간이 길어지는 것을 대비하여 메소드 전체가 아닌 문제를 발생시킬 부분에만 synchronzied블록을 사용한다 

ex) 

 

   
   //다른 A메소드가 monitoring Lock을 얻게 된다 
   
   public synchronized void playMusicA(){
        for(int i = 0; i < 10; i ++){
            System.out.println("신나는 음악!!!");
            try {
                Thread.sleep((int)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }     
    } //playMusicA

 

ex) 문제를 발생시킬 부분에만 synchronized블록 사용 

 

    public void playMusicB(){
        for(int i = 0; i < 10; i ++){
            synchronized(this){
                System.out.println("슬픈 음악!!!");
            }
            try {
                Thread.sleep((int)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } // for        
    } //playMusicB

 

주의사항 

- 3개의 쓰레드를 start() 시킬 때 실행시키는 순서는 상관없이 3개의 쓰레드가 mornitoring Lock을 얻기 위해 경쟁함 

-  먼저 Monitoring Lock을 얻은 synchronized메서드가 다 출력됨 

- 남은 2개의 쓰레드가 경쟁 

- monitoring Lock을 얻은 쓰레드가  for문 중 하나에만 동기화가 걸려 있기에 한 번 출력 후 모니터링 락 반환 

- 다시 경쟁 

 

 

 

 

 

 

 

 

 

 

 

 

*위 게시물은 프로그래머스<자바중급> 강의를 복습하며 작성한 글입니다*