본문 바로가기
Programming Language/Java

[자바] 쓰레드와 공유 객체 및 동기화

by ggyongi 2021. 11. 17.
반응형
package first_project;

public class MusicBox {
	//Dance music이란 메시지가 1초이하로 쉬면서 10번 반복출력
    public void playMusicA(){
        for(int i = 0; i < 10; i ++){
            System.out.println("Dance music");
            try {
                Thread.sleep((int)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } // for        
    } //playMusicA

    //Ballad music이란 메시지가 1초이하로 쉬면서 10번 반복출력
    public void playMusicB(){
        for(int i = 0; i < 10; i ++){
            System.out.println("Ballad music");
            try {
                Thread.sleep((int)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } // for        
    } //playMusicB
    //Cafe music이란 메시지가 1초이하로 쉬면서 10번 반복출력
    public void playMusicC(){
        for(int i = 0; i < 10; i ++){
            System.out.println("Cafe music");
            try {
                Thread.sleep((int)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } // for        
    } //playMusicC 
}

 

package first_project;

public class MusicPlayer extends Thread{
	int type;
	MusicBox musicBox;
	
	public MusicPlayer(int type, MusicBox musicBox) {
		this.type = type;
		this.musicBox = musicBox;
	}

	@Override
	public void run() {
		switch(type){
        case 1 : musicBox.playMusicA(); break;
        case 2 : musicBox.playMusicB(); break;
        case 3 : musicBox.playMusicC(); break;
        
		}
			
	}

}

 

package first_project;

public class MusicBoxTest {

	public static void main(String[] args) {
		MusicBox musicBox = new MusicBox();
		
		MusicPlayer kim = new MusicPlayer(1, musicBox);
		MusicPlayer lee = new MusicPlayer(2, musicBox);
		MusicPlayer park = new MusicPlayer(3, musicBox);
		
		kim.start();
		lee.start();
		park.start();
		
	}

}

출력 결과(랜덤하게 10번씩 출력된다.)

Dance music
Cafe music
Ballad music
Cafe music
Dance music
Ballad music
Cafe music
Dance music
Dance music
Dance music
Ballad music

이하 생략

 

 

<동기화>

그런데, 멀티스레딩에서는 항상 동기화에 신경써줘야한다. 동기화를 해주지 않으면 문제가 발생할 수 있기 때문.

이때 메서드 앞에  synchronized를 붙이면 메서드 공유객체가 가진 메소드를 동시에 호출 되지 않도록 할 수 있음.


여러개의 Thread들이 공유객체의 메소드를 사용할 때 메소드에 synchronized가 붙어 있을 경우 먼저 호출한 메소드가 객체의 사용권(Monitoring Lock)을 얻는다.

 

위의 실행했던 코드의 메서드 앞에 아래와 같이 synchronized를 각각 붙여주고 실행하면 동기화가 된다.

//Dance music이란 메시지가 1초이하로 쉬면서 10번 반복출력
    public synchronized void playMusicA(){
        for(int i = 0; i < 10; i ++){
            System.out.println("Dance music");
            try {
                Thread.sleep((int)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } // for        
    } //playMusicA

새로운 출력 결과(메소드 하나가 모두 실행된 후에 다음 메소드가 실행된다.)

Dance music
Dance music
Dance music
Dance music
Dance music
Dance music
Dance music
Dance music
Dance music
Dance music
Cafe music
Cafe music
Cafe music
Cafe music
Cafe music
Cafe music
Cafe music
Cafe music
Cafe music
Cafe music
Ballad music
Ballad music
Ballad music
Ballad music
Ballad music
Ballad music
Ballad music
Ballad music
Ballad music
Ballad music

다른 쓰레드들은 모니터링 락을 놓을때까지 대기한다.
synchronized를 붙히지 않은 메소드는 다른 쓰레드들이 synchronized메소드를 실행하면서 모니터링 락을 획득했다 하더라도, 그것과 상관없이 실행된다.
synchronized를 메소드에 붙혀서 사용 할 경우, 메소드의 코드가 길어지면, 마지막에 대기하는 쓰레드가 너무 오래 기다리는것을 막기위해서 메소드에 synchronized를 붙이지 않고, 문제가 있을것 같은 부분만 synchronized블록을 사용한다.

예시

   public void playMusicA(){
        for(int i = 0; i < 10; i ++){
        	synchronized(this) {
        		System.out.println("Dance music");
        	}
            
            try {
                Thread.sleep((int)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } // for        
    } //playMusicA

 

나머지는 메서드에 synchronized를 붙이고 playMusicA에만 위에처럼 블록을 사용했을 경우 출력 결과는?

Dance music
Ballad music
Ballad music
Ballad music
Ballad music
Ballad music
Ballad music
Ballad music
Ballad music
Ballad music
Ballad music
Dance music
Cafe music
Cafe music
Cafe music
Cafe music
Cafe music
Cafe music
Cafe music
Cafe music
Cafe music
Cafe music
Dance music
Dance music
Dance music
Dance music
Dance music
Dance music
Dance music
Dance music

왜 이렇게 되는지 이해할 수 있어야 한다.

 

비전공자 네카라 신입 취업 노하우

시행착오 끝에 얻어낸 취업 노하우가 모두 담긴 전자책!

kmong.com

댓글