자바 메모리 모델 JMM의 6 심도 있는 이해synchronized(2)

5184 단어
자세히 보기

본고는 미완성 자바 메모리 모델 JMM의 6가지 깊이 있는 이해synchronized(1)


3.7 잠금 해제


동기화 자물쇠를 없애는 것은 JVM의 또 다른 자물쇠의 최적화이다. 이런 최적화는 더욱 철저하다. JVM은 실행할 때 JIT컴파일링(어떤 코드가 처음 실행될 때 컴파일링을 하는 것으로 이해할 수 있으며 즉각컴파일링이라고도 부른다)을 통해 코드에 동기화를 추가하도록 요구하지만 디지털 탈출 기술 분석을 통해 공유 데이터 경쟁이 존재할 수 없다는 것을 발견했다. 이때 JVM은 이런 불필요한 동기화 자물쇠를 제거한다.그래서 자물쇠 제거는 무의미한 요청 자물쇠의 시간을 절약할 수 있다. 그러면 데이터 경쟁이 존재하지 않는 것을 뻔히 알면서도 왜 동기화 작업을 했는가?프로그래머로서 이런 코드를 쓸 수는 없지만 때때로 프로그램은 우리가 생각하는 대로 되지 않는다. 우리는 동기화 자물쇠를 사용하지 않지만 JDK에 내장된 API를 사용할 때stringBuffer, Vector,HashTable 등 은근한 동기화 자물쇠 작업이 존재한다.예를 들어 StringBuffer의 append () 방법, Vector의dd () 방법 등이다.
public void add(String str1, String str2) {
	//StringBuffer     ,  sb   append     ,          
	//  sb          ,JVM         
	StringBuffer sb = new StringBuffer();
	sb.append(str1)
	  .append(str2);
}

상기 코드는 매우 흔하죠. 특히 SQL, HQL 등 조작을 연결할 때 이 곳의 sb 대상은 국부 변수이고 다른 라인에 인용되지 않기 때문에StringBuffer의 append 방법은 동기화 방법이기 때문에 JVM은 자물쇠 제거 메커니즘을 통해 자물쇠를 제거합니다.
 

3.7 잠금 강화


원칙적으로 우리는 코드를 작성할 때 상동기 블록의 작용 범위가 가능한 한 적고 데이터를 공유하는 실제 작용 영역에서만 동기화하는 것을 추천한다. 이것은 동기화가 필요한 조작이 가능한 한 적고 자물쇠 경쟁이 존재하면 잠금 대기 라인이 가능한 한 빨리 자물쇠를 받을 수 있도록 하기 위해서이다.대부분의 경우 이러한 원칙은 문제가 없다. 그러나 만약에 일련의 연속 조작이 같은 자물쇠에 대한 반복적인 잠금과 잠금 해제, 심지어 순환체에서 반복적인 잠금 해제 조작을 한다면 이런 상황은 라인 경쟁이 없어도 잦은 상호 배척 동기화 조작을 하면 불필요한 성능 손실을 초래할 수 있다.
자물쇠 조화란 여러 개의 연속적인 잠금, 잠금 해제 작업을 연결하여 하나의 범위가 더 큰 자물쇠로 확장하는 것이다. 다음 코드의 예는 다음과 같다.
 
public void vectorTest(){
	Vector vector = new Vector();
	for(int i = 0 ; i < 10 ; i++){
		vector.add(i + "");
	}

	System.out.println(vector);
}
상기 코드는 순환체에서 집합 요소 추가 작업을 하는 데 흔히 볼 수 있는 것이다. 우리는vector의dd방법은 동기화 방법이라는 것을 알고 있다. 매번dd는 잠금을 추가해야 하고 실행이 끝난 후에 잠금 해제 작업을 해야 한다. 이때 JVM이 같은 대상(vector)에 대한 연속 잠금, 잠금 해제 작업을 검출하면 더욱 넓은 범위의 잠금, 잠금 해제 작업을 합병하고 잠금 해제 작업을 for순환 밖으로 옮긴다.한 번의 잠금 해제 작업으로 여러 번의 잠금 해제 작업을 대체합니다.
 

3.8 synchronized는interrupt에 의해 중단될 수 없음


스레드의 인터럽트 방법은 인터럽트 상태에 있거나 인터럽트 작업을 준비하고 있는 스레드만 인터럽트할 수 있다는 것이다. 여기서 인터럽트는 사실 Join,wait,sleep 등 방법을 사용해서 스레드가 들어오는 WAITING/TIMED 를 가리킨다.WAITING 상태는 중단 작업을 감지하여 중단 이상을 제거할 수 있기 때문입니다.이른바 synchronized는interrupt 방법에 의해 중단될 수 없다. 이것은 라인이synchronized 방법이나 코드 블록에 실행될 때 대상 자물쇠가 점용되어 라인이 하부의 Park 방법을 호출하여 죽는 상태로 들어가야 한다는 것을 말한다. 이때 라인도 사실상 막힌 상태로 들어갔지만 표시되지 않은 호출로 인해 중단 이상을 던질 수 있는 방법을 던질 수 있다.이로 인해 막힌 라인이 막힌 상태에서 회복되지 못해 라인이 잠겨 기다리는 막힌 상태에 있다.다음 코드 예제에서는 를 설명합니다.
public class ThreadTest implements Runnable{
	
	public ThreadTest() {
		//           
        new Thread() {
            public void run() {
                f(); // Lock acquired by this thread
            }
        }.start();
	}

	public synchronized void f() {
        System.out.println("Trying to call f()");
        while(true) // Never releases lock
            Thread.yield();
    }
	
	public void run() {
        //    
        while (true) {
            if (Thread.interrupted()) {
                System.out.println("    !!");
                break;
            } else {
                f();
            }
        }
    }

	public static void main(String[] args) throws InterruptedException {
		Thread t = new Thread(new ThreadTest()); 
		t.start();
        TimeUnit.SECONDS.sleep(1);
        //    ,    
        t.interrupt();
	}

}

ThreadTest 예시를 만들 때 그 구조 방법에서synchronized 방법 f를 즉시 실행했다. f 방법은 대상 자물쇠를 계속 가지게 할 수 있다. 루트 t가 만들어져도 f 방법을 호출할 때 자물쇠 대기 상태이고 막힌 상태이다. 나중에interrupt 중단 방법을 호출했지만 루트 t는 중단될 수 없다. 중단 이상을 던질 수 있는 방법이 없기 때문이다.대상 자물쇠를 가져올 때까지 루트 t는 기다릴 수 있습니다.
 

3.9 synchronized 잠금 및 잠금 최적화 요약


자물쇠
의 원리
장점
결점
적용 장면
편향 자물쇠
만약 한 라인이 자물쇠를 얻었다면, 이 자물쇠는 편향 모드에 들어갈 것입니다. 이 라인이 다시 자물쇠를 요청할 때, 더 이상 동기화 작업을 할 필요가 없습니다
중복 수령/해제 비용 절감
만약 경쟁이 치열하다면, 추가 잠금 해제의 소모를 가져올 것이다
대부분의 경우 같은 라인만 있고 동기화 블록의 장면을 여러 번 방문하여 경쟁이 존재하지 않는다
경량급 자물쇠
CAS 명령 및 자전거 조작만으로 잠금 해제
스레드가 사용자 상태에서 내부 핵 상태로 전환되는 소모를 피하고 스레드가 막히지 않으며 프로그램의 응답 속도를 높인다
잠금 경쟁이 있을 경우 CPU가 자전거로 소모됨
경쟁이 존재하지 않고 다중 스레드가 번갈아 집행되며 동기화 블록이 비교적 빠른 장면을 집행한다
헤비급 자물쇠
운영체제의 밑바닥 실현을 통해 경쟁의 라인을 막고 막힌 라인을 깨우다
다른 상황에 비해 장점이 거의 없다
스레드 막힘/깨우기는 사용자 상태와 내부 핵 상태 사이를 전환해야 하기 때문에 대량의 원가를 소모하고 막힘으로 인해 스레드 응답이 느려진다
경쟁이 치열하고 동기화 코드 블록의 논리가 복잡하여 많은 시간을 차지하는 장면
자전/자전 적용
여러 차례 무의미한 지령을 집행함으로써 불필요한 마운트 및 복구 라인 시 상태 전환으로 인한 성능 소모를 피한다
스레드가 사용자 상태에서 내부 핵 상태로 전환되는 소모를 피했다
CPU 사용량 증가
경량급 자물쇠와 중량급 자물쇠가 경쟁을 일으킬 때 내핵 상태로 전환하기 전에
잠금 해제
데이터 탈출 기술 분석을 통해 데이터 공유가 존재하지 않는 동기화 자물쇠에 대해 자물쇠 제거를 실시하다
불필요한 획득/방출 자물쇠의 소모를 없애다
JVM의 JIT 컴파일링에 전적으로 의존하는 JVM 자체
JVM의 인스턴트 컴파일링(JDK 기본 API)
자물쇠 조화
동일한 잠금 대상에 대한 여러 번의 가져오기/해제 작업을 한 번의 가져오기/해제 작업으로 확장합니다
중복 수령/해제 비용 절감
JVM에 전적으로 의존
주기 작업의 장면에 동기화 블록 배치
 
 
 
 
 
 
 
 
 

좋은 웹페이지 즐겨찾기