Synchronized Block, Synchronized method
동기화(Synchronized)
- 공유 데이터(나머지 synchronized 된부분) 에 lock을 걸어 작업중이던 쓰레드가 마칠때까지 다른 쓰레드에게 제어권이 넘어가지 않게 보호한다.
- 교착상태에 주의해야 한다.
쓰레드는 같은 프로세스 내 데이터를 공유하기 때문에 일관성에 영향을 끼칠 수 있다.
만약 공유하는 자원을 처리하던 중 다른 쓰레드가 접근하기라도 한다면 ?
즉 동기화를 통해, 위와 같은 상황을 방지하고 어느 한 시점에 하나의 쓰레드만 접근하여 자원을 선점하고 프로그래머는 이를 효율적으로 관리할 필요가 있다.
예를 들어, 작업 중인 문서에 누군가 들어와 편집을 해서 내가 했던 자료가 날라갔다고 가정하면 큰 낭패 일 것이다. 작업중인 문서에 lock을 걸어 다른 사람의 편집권한을 막는 것과 같은 이치라고 생각하면 된다.
ex) Singleton Pattern의 인스턴스를 여러 객체가 접근 할 때, Static으로 정의된 객체를 여러 객체가 접근 할 때, 하나의 객체에 여러 개의 쓰레드가 접근하려고 할 때..
사용법
(1) 특정 객체 인스턴스에 lock을 걸려고 할 때 - synchronized block
private Worker wokrer = new Worker();
public void work(){
synchronized(worker){
//input
}
}
(2) 메소드에 lock을 걸 때 - synchronized method
public synchronized work(){
//input code
Worker worker = new Worker();
}
특정 인스턴스의 사용을 동기화 할 것이냐? 혹은 메소드 자체를 동기화 할 것이냐?의 구분의 차이로 인식하면 쉬울 것 같다.
사소하지만 주의깊게 생각해야 할 점이 있다면, (1) 번의 경우 synchronized 된 부분이 임계 영역이라면, (2) 번의 경우 메소드 전체가 임계영역이 된다는 점이다.
Sample Code
class Worker { private Object obj; private int count=0; public Worker() { } public synchronized void writeData(Object obj) { this.obj = obj; count++; } public Object getObj() { return obj; } public void setObj(Object obj) { this.obj = obj; } @Override public synchronized String toString() { return "Worker [obj=" + obj + ", count=" + count + "]"; } } public class Main { public static void main(String[] args) {
//Worker라는 하나의 인스턴스를 공유할 것이다. Worker worker = new Worker(); Thread thread1 = new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub while (true) { try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } worker.writeData("Writer1"); System.out.println("Data Print :"+worker.toString()); } } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub while (true) { try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } worker.writeData("Writer2"); System.out.println("Data Print :"+worker.toString()); } } }); thread1.start(); thread2.start(); } }
- WriteData 메소드와 toString 메소드를 동기화함에 따라 순차적인 Count 증가 및 Data를 Write할 수 있었다.
=>결과 출력
위의 방법처럼 synchronized 된 메소드를 구성했다면 , 객체를 synchronized 하여 구성하는 것도 쉽게 할 수 있을 것이다.
'programming > Java' 카테고리의 다른 글
# NIO - Selector (0) | 2018.05.19 |
---|---|
# chatting program 구현 / 네트워크 교육과정 (4일차) (1) | 2018.03.22 |
# network, socket / 네트워크 교육과정 (3일차) (0) | 2018.03.22 |
# IO , Stream / 네트워크 교육과정 (2일차) (0) | 2018.03.19 |
# Thread / 네트워크 교육과정 (1일차) (0) | 2018.03.19 |