TIL (21/06/16)

Java Synchronized

핵심1: Method에 거는 syncronized 키워드는 해당 함수가 포함된 객체(this)에 Lock을 거는 것과 같다.

핵심2: Static Method에 거는 syncronized 키워드는 해당 함수가 포함된 Class에 Lock을 거는 것과 같다.

#1 서로 다른 Thread로 call() 함수를 호출하지만, synchronized 키워드의 객체락으로 인해 Thread-safe하다.

// #1
public class TestClass {
    private String tMsg;

    public static void main(String[] args) {
        TestClass demo = new TestClass();

        System.out.println("Test Start !");
        new Thread(() -> {
            for (int i=0; i<100; i++) {
                demo.call("Caller1");
            }
        }).start();

        new Thread(() -> {
            for (int i=0; i<100; i++) {
                demo.call("Caller2");
            }
        }).start();

        System.out.println("Test End !");
    }

    public synchronized void call(String caller) {
        tMsg = caller;

        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
        
        if (!tMsg.equalsIgnoreCase(caller)) {
            System.out.printf("tMsg : %s <-> caller : %s%n", tMsg, caller);
        }
    }
}

#2 서로 다른 Thread가 call() 함수를 호출하며 멤버변수의 값이 Thread-safe 하지 않아 Message가 출력된다.

// #2
public void call(String caller) {
        tMsg = caller;

        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
        
        if (!tMsg.equalsIgnoreCase(caller)) {
            System.out.printf("tMsg : %s <-> caller : %s%n", tMsg, caller);
        }
    }
// #2 Log
Test Start !
Test End !
tMsg : Caller2 <-> caller : Caller1
tMsg : Caller1 <-> caller : Caller2
tMsg : Caller2 <-> caller : Caller1
tMsg : Caller1 <-> caller : Caller2
tMsg : Caller2 <-> caller : Caller1
tMsg : Caller1 <-> caller : Caller2
tMsg : Caller2 <-> caller : Caller1
tMsg : Caller1 <-> caller : Caller2
.
.
.

좋은 웹페이지 즐겨찾기