[JAVA] Thread와 공유객체

ho's·2022년 5월 26일
0

🎪 Thread와 공유객체

하나의 인스턴스를 여러개의 쓰레드가 함께 사용하는 경우를 말한다.
즉, 인스턴스는 하나인데 스레드는 여러개이다.

🎐 하나의 객체를 여러개의 쓰레드에서 사용

SharedObject so = new SharedObject();
Thread1 t1 = new Thread1(so);
Thread2 t2 = new Thread2(so);
Thread3 t3 = new Thread3(so);

하나의 인스턴스 so를 t1,t2,t3 3개의 인스턴스가 참조하고있다.

📘 Synchronized

  • Java에서는 키워드 synchronized를 이용해 공유 객체에 동시에 실행되면 안되는 메소드나 블록을 보호할 수 있다.
  • 공유 객체에서 동시에 실행되면 안되는 부분과 동시에 실행 되도 되는 부분을 잘 구분한 후, 동시에 실행되면 안되는 부분에 synchronized 키워드를 이용해 제어 할 수 있다.
  • synchronize는 메소드에 붙여 사용하거나 메소드 안의 특정 부분을 블록으로 감싸 사용할 수 있다.
synchronize(객체의 필드) {
	// 동시에 실행되면 안되는 코드.
}

sychronized 리턴타입 메소드명(파라미터){
	// 동시에 실행되면 안되는 코드.
}

JAVA의 정석
한 쓰레드가 진행 중인 작업을 다른 쓰레드가 간섭하지 못하도록 막는 것을 '쓰레드의 동기화'라고 한다.

📄 Synchronized 예제 코드

package totojava.thread;

public class MagicBox {
    public void a() {
        for (int i = 0; i < 5; i++) {
            System.out.print("a");
            try {
                Thread.sleep((int) Math.random() * 1000); // 0 ~ 1000
            } catch (Exception x) {
            }
        }//for
    }

    public void b() {
        for (int i = 0; i < 5; i++) {
            System.out.print("b");
            try {
                Thread.sleep((int) Math.random() * 1000); // 0 ~ 1000
            } catch (Exception x) {
            }
        }//for
    }

    public void c() {
        for (int i = 0; i < 5; i++) {
            System.out.print("c");
            try {
                Thread.sleep((int) Math.random() * 1000); // 0 ~ 1000
            } catch (Exception x) {
            }
        }//for

    }
}
package totojava.thread;

public class MagicBoxExam {
    public static void main(String[] args) {
        MagicBox magicBox = new MagicBox();

        Player player1 = new Player("kim", magicBox);
        Player player2 = new Player("lee", magicBox);
        Player player3 = new Player("kang", magicBox);

        player1.start();
        player2.start();
        player3.start();

    }
}
package totojava.thread;

public class Player extends Thread {
    private String name;
    private MagicBox magicBox;

    public Player(String name, MagicBox magicBox){
        this.name = name;
        this.magicBox = magicBox;
    }

    @Override
    public void run(){
        if("kim".equals(name)){
            magicBox.a();
        }else if("lee".equals(name)){
            magicBox.b();
        }else if("kang".equals(name)){
            magicBox.c();
        }
    }
}
  • MagicBox 클래스는 a(),b(),c()메소드를 갖고 실행시키면 "a","b","c"를 출력한다.

  • MagicBoxExam 클래스는 MagicBox, Player의 객체를 만들고, player에서 실행시킨다.

위의 코드의 실행 결과

📄 a,b가 같이 호출 되면 고장이 난다고 할 때, 어떻게 처리할 것 인가?

Synchronized 를 이용하자.

a,b는 같이 실행되면 안된다.

다음과 같이 같이 사용되면 안되는 곳에 synchronized를 붙이면 된다!

profile
그래야만 한다

0개의 댓글