본문 바로가기

공부방/Java

synchronized (this) ? synchronized (Class.class) ?

싱글턴 패턴을 작성하고 궁금한게 생겼다. synchronized () {} 에서 () 안에 들어가는게 .class였는데 .. 다른데 보면 this라는걸 사용하기도 한다. 그래서 차이점이 뭔지 궁금했는데 .. 여기저기 물어봐서 결국 알게 되었다. 그냥 뭐 단순하게 '지금 내 인스턴스'를 락 걸던가 .. 아니면 '.class의 모든 인스턴스'에 락을 걸것인지의 차이점이다.  이에 대한 샘플 소스는 다음과 같다.


ThisSync.java
  1. package pupustory.sync.sample;  
  2.   
  3. public class ThisSync extends Thread {  
  4.     private final String MSG = this.toString()+"\t";  
  5.     public void run() {  
  6.         System.out.println(MSG+"synchronized (this) { ... }");  
  7.         synchronized (this) {  
  8.             System.out.println(MSG+"It's synchronized (this) block !!");  
  9.             System.out.println(MSG+"Sleep(100) start !!");  
  10.             try { Thread.sleep(100);} catch (Exception e) {e.printStackTrace();}  
  11.             System.out.println(MSG+"Sleep(100) end !!");  
  12.         }  
  13.     }  
  14.   
  15. }  

ClassSync.java
  1. package pupustory.sync.sample;  
  2.   
  3. public class ClassSync extends Thread {  
  4.     private final String MSG = this.toString()+"\t";  
  5.     public void run() {  
  6.         System.out.println(MSG+"synchronized (ClassSync.class) { ... }");  
  7.         synchronized (ClassSync.class) {  
  8.             System.out.println(MSG+"It's synchronized (ClassSync.class) block !!");  
  9.             System.out.println(MSG+"Sleep(100) start !!");  
  10.             try { Thread.sleep(100);} catch (Exception e) {e.printStackTrace();}  
  11.             System.out.println(MSG+"Sleep(100) end !!");  
  12.         }  
  13.     }  
  14. }  

StartApp.java
  1. package pupustory.sync.sample;  
  2.   
  3. public class StartApp {  
  4.     public static void main(String ar[]) {  
  5.         // Class Sync Thread Test  
  6. //      Thread ClassThread1 = new ClassSync();  
  7. //      Thread ClassThread2 = new ClassSync();  
  8. //      Thread ClassThread3 = new ClassSync();  
  9. //        
  10. //      ClassThread1.start();  
  11. //      ClassThread2.start();  
  12. //      ClassThread3.start();  
  13.           
  14.         // This Sync Thread Test          
  15.         Thread ThisThread1 = new ThisSync();  
  16.         Thread ThisThread2 = new ThisSync();  
  17.         Thread ThisThread3 = new ThisSync();  
  18.   
  19.         ThisThread1.start();  
  20.         ThisThread2.start();  
  21.         ThisThread3.start();  
  22.     }  
  23. }  

샘플 소스 결과 (ClassSync.java)

Thread[Thread-0,5,main]    synchronized (ClassSync.class) { ... } 
Thread[Thread-2,5,main]    synchronized (ClassSync.class) { ... } 
Thread[Thread-2,5,main]    It's synchronized (ClassSync.class) block !! 
Thread[Thread-2,5,main]    Sleep(100) start !! 
Thread[Thread-1,5,main]    synchronized (ClassSync.class) { ... } 
Thread[Thread-2,5,main]    Sleep(100) end !! 
Thread[Thread-0,5,main]    It's synchronized (ClassSync.class) block !! 
Thread[Thread-0,5,main]    Sleep(100) start !! 
Thread[Thread-0,5,main]    Sleep(100) end !! 
Thread[Thread-1,5,main]    It's synchronized (ClassSync.class) block !! 
Thread[Thread-1,5,main]    Sleep(100) start !! 
Thread[Thread-1,5,main]    Sleep(100) end !!

샘플 소스 결과 (ThisSync.java)

Thread[Thread-0,5,main]    synchronized (this) { ... } 
Thread[Thread-0,5,main]    It's synchronized (this) block !! 
Thread[Thread-0,5,main]    Sleep(100) start !! 
Thread[Thread-1,5,main]    synchronized (this) { ... } 
Thread[Thread-1,5,main]    It's synchronized (this) block !! 
Thread[Thread-1,5,main]    Sleep(100) start !! 
Thread[Thread-2,5,main]    synchronized (this) { ... } 
Thread[Thread-2,5,main]    It's synchronized (this) block !! 
Thread[Thread-2,5,main]    Sleep(100) start !! 
Thread[Thread-0,5,main]    Sleep(100) end !! 
Thread[Thread-1,5,main]    Sleep(100) end !! 
Thread[Thread-2,5,main]    Sleep(100) end !!

ClassSync는 모든 쓰레드가 수행하려고 할때 동기화가 걸려있으므로 먼저 들어간 쓰레드가 끝나길 기다렸다 다음 쓰레드가 들어가게 된다. 따라서 하나가 끝나야 다음 하나가 처리되므로 start !!와 end !!가 블럭의 앞,뒤처럼 맞게 나온다.

ThisSync는 지금 현재의 쓰레드에 대해 동기화가 걸려있으므로 다른 쓰레드가 같은 가지고 있는 인스턴스에 대해선 관여하지 않는다. 따라서 동시에 시작한 쓰레드 들은 자기만 사용하기 떄문에 그냥 end !!가 주루룩 나오게 된다.



출처 : http://pupustory.tistory.com/149

'공부방 > Java' 카테고리의 다른 글

멀티 스레드(Thread) 구현하기  (0) 2012.02.13
쓰레드의 Wait()와 notify()사용  (0) 2012.02.13
자바 쓰레드 프로그래밍  (0) 2012.02.13
JAVA Thread  (0) 2012.02.13
Java의 synchronized 분석  (0) 2012.02.13