본문 바로가기
IT/Java

Synchronized 관련

by 성준하이 2024. 11. 13.
반응형

이번 포스팅에서는 lock 을 걸기 위해 자주 사용하는 Synchronized 에 대해서 예제로 테스트 해볼 것이다.

 

테스트는 크게 2가지로 진행을 할 예정이고, 각 테스트마다 static 일 경우를 함께 테스트 해볼 것이다.

 

1. Synchronized Method

2. Synchronized Block

 

1. Synchronized Method

 

아래와 같이 Synchronized Method 를 만들어 두고 main 클래스에서 동시에 호출을 시켜볼 예정이다.

Synchronized Method  Synchronized Static Method 
public synchronized void run(String id) {
     System.out.println(id+ " lock start");
     try {
         Thread.sleep(1000);
     }catch (Exception e) {
         e.printStackTrace();
     }
     System.out.println(id + " lock end");
}
public static synchronized void run(String id) {
     System.out.println(id+ " lock start");
     try {
         Thread.sleep(1000);
     }catch (Exception e) {
         e.printStackTrace();
     }
     System.out.println(id + " lock end");
}
main 코드 Synchronized
Method 결과
Synchronized
static
Method 결과
설명
SyncTest a = new SyncTest();

a.run("1");
a.run("2");
1 lock start
1 lock end
2 lock start
2 lock end
1 lock start
1 lock end
2 lock start
2 lock end
하나의 객체로 호출할 경우 lock
SyncTest a = new SyncTest();
SyncTest a2 = new SyncTest();

a.run("1");
a2.run("2");
1 lock start
1 lock end
2 lock start
2 lock end
1 lock start
1 lock end
2 lock start
2 lock end
별도의 객체로 만들고 호출할 경우 lock
Thread thread1 = new Thread(new Runnable() {
     @Override
     public void run() {
         a.run("1");
     }
});


Thread thread2 = new Thread(new Runnable() {
     @Override
     public void run() {
         a.run("2");
     }
});

thread1.start();
thread2.start();
1 lock start
1 lock end
2 lock start
2 lock end
1 lock start
1 lock end
2 lock start
2 lock end
Thread를 생성하여 하나의 객체로 호출할 경우 lock
Thread thread1 = new Thread(new Runnable() {
     @Override
     public void run() {
         a.run("1");
     }
});


Thread thread2 = new Thread(new Runnable() {
     @Override
     public void run() {
         a2.run("2");
     }
});

thread1.start();
thread2.start();
1 lock start
2 lock start
2 lock end
1 lock end
1 lock start
1 lock end
2 lock start
2 lock end
Thread 를 생성하여 별도의 객체로 호출할 경우 lock 안걸림.

하지만 static 로 된 메서드를 호출 할 경우 일반 static 처럼 인스턴스 단위가 아닌 클래스 단위로 lock 이 발생한다.

 

2. Synchronized Block

 

아래와 같이 Synchronized Block 를 만들어 두고 main 클래스에서 동시에 호출을 시켜볼 예정이다.

Synchronized Block Synchronized Static Block
public void run(String id) {
     synchronized(this) {
         System.out.println(id+ " lock start");
         try {
             Thread.sleep(1000);
         }catch (Exception e) {
             e.printStackTrace();
         }
         System.out.println(id + " lock end");
     }
}
public static void run(String id) {
     synchronized(SyncTest.class) { //클래스 명으로 변경
         System.out.println(id+ " lock start");
         try {
             Thread.sleep(1000);
         }catch (Exception e) {
             e.printStackTrace();
         }
         System.out.println(id + " lock end");
     }
}
main 코드 Synchronized
Block 결과
Synchronized
static
Method 결과
설명
SyncTest a = new SyncTest();

a.run("1");
a.run("2");
1 lock start
1 lock end
2 lock start
2 lock end
1 lock start
1 lock end
2 lock start
2 lock end
하나의 객체로 호출할 경우 lock
SyncTest a = new SyncTest();
SyncTest a2 = new SyncTest();

a.run("1");
a2.run("2");
1 lock start
1 lock end
2 lock start
2 lock end
1 lock start
1 lock end
2 lock start
2 lock end
별도의 객체로 만들고 호출할 경우 lock
Thread thread1 = new Thread(new Runnable() {
     @Override
     public void run() {
         a.run("1");
     }
});


Thread thread2 = new Thread(new Runnable() {
     @Override
     public void run() {
         a.run("2");
     }
});

thread1.start();
thread2.start();
1 lock start
1 lock end
2 lock start
2 lock end
1 lock start
1 lock end
2 lock start
2 lock end
Thread를 생성하여 하나의 객체로 호출할 경우 lock
Thread thread1 = new Thread(new Runnable() {
     @Override
     public void run() {
         a.run("1");
     }
});


Thread thread2 = new Thread(new Runnable() {
     @Override
     public void run() {
         a2.run("2");
     }
});

thread1.start();
thread2.start();
1 lock start
2 lock start
2 lock end
1 lock end
1 lock start
1 lock end
2 lock start
2 lock end
Thread 를 생성하여 별도의 객체로 호출할 경우 lock 안걸림.

하지만 static 로 된 메서드를 호출 할 경우 일반 static 처럼 인스턴스 단위가 아닌 클래스 단위로 lock 이 발생한다.

 

 

결론

synchronized method

  • 인스턴스 단위로 lock
  • 메서드가 시작될 때부터 종료될 때까지 동기화가 발생
  • 동일 인스턴스내에서 synchronized키워드가 적용된 곳에서는 lock을 공유

 

synchronized block

  • 인스턴스 단위로 lock
  • block내부에서 동기화가 발생한다.
반응형

댓글