고급자바_Thread_동기화

wstudee·2020년 9월 22일
0

JAVA_고급

목록 보기
7/19

공유객체

  • 하나의 객체를 여러개의 Thread가 사용

  • 스레드에서 데이터를 공통으로 사용하는 방법
    1. 공통으로 사용할 데이터를 클래스로 정의한다.
    2. 공통으로 사용할 클래스의 인스턴스를 만든다.
    3. 이 인스턴스를 각각의 스레드에 넘겨준다.
    4. 각각의 스레드는 이 인스턴스의 참조값을 저장한 변수를 이용하여 공통데이터를 사용한다.

volatile

  • 선언된 변수를 컴파일러의 최적화 대상에서 제외시킴.
    => 값이 변경되는 즉시 변수에 적용
  • 다중 스레드에서 하나의 변수가 완벽하게 한번에 작동되도록 보장하는 키워드
    => 일종의 동기화

동기화

  • 과도한 동기화는 프로그램 성능을 저하시킴.
  • 필요한 영역에 선별적으로 사용.

동기화 메서드

  • 메서드 자체에 동기화 처리 하기 : synchronized
  • 여러 개의 Thread 들이 공유객체의 synchronized 메서드를 사용할 때 먼저 호출한 객체가 사용권 획득
  • synchronized 아닌 메서드는 다른 스레드들이 synchronized 메서드 실행하면서 사용권을 획득했다 하더라도 상관없이 실행됨
  • 메서드 코드가 길어지면 마지막에 대기하는 스레드가 너무 오래 기다리는 것을 막기 위해서 동기화블럭 사용

동기화 블럭

  • 메서드 내 문제 발생 여지가 있을만한 임계영역에 동기화 처리
  • synchronized(this){...}
  • 필요한 영역(ex.동시에 작업하면 안되는 영역)만 동기화처리 가능
  • 특정 스레드 객체가 이 영역 실행하는 중에 다른 스레드는 Blocked

lock 객체

  • Lock 클래스 이용
  • Lock 객체 생성 : 되도록이면 private final(다른 객체에서 접근 못하게)
  • lock() : 동기화 시작
  • unlock() : 동기화 해제 (반드시 해제 해야함)
  • synchronized 단점 : 동기화 최대범위가 메서드
  • lock()은 광범위하게 사용가능하지만 반드시 해제 필요!
  • try~catch 블럭 사용할 경우에는 finally 블럭에서 unlock()
    예외발생에 관계없이 lock() 해제해야하기 때문
private final ReentrantLock lock = new ReentrantLock();
   
lock.lock(); // 락 설정 
...
lock.unlock(); // 락 해제 

Collections 동기화

  • Vector, Hashtable 등 예전부터 존재하던 Collection 클래스는 내부에 동기화처리 되어있음
  • 최근 새로 구성된 Collection 들은 동기화처리 되어있지 않음
  • 동기화 필요한 프로그램에서 이런 Collection 사용하려면 동기화처리 후 사용해야함
  • Collections의 정적메서드 중 synchronized로 시작하는 메서드 이용
    (Collections 클래스가 제공하는 동기화메서드 )
private static List<Integer> list = 
	Collections.synchronizedList(new ArrayList<>());

0개의 댓글