java 스레드 동기화 문제 해결 5가지 방법

3709 단어 JAVA 동시 시리즈

참조:


https://www.cnblogs.com/goody9807/p/6522176.html

배경:


루틴을 만드는 두 가지 방법: 1. runnable Thread 실례 대상은 단일 실례로 Thread에 전달되기 때문에 여러 개의 루틴을 만들어서 하나의 실례 대상을 공유하고 그 안의 속성도 모두 공유한다.2. Thread 다중 스레드 작동 원리: 스레드 1: 작동 단계 – 작업 메모리 – 총 메모리.스레드 2: 운영 단계 – 작업 메모리 – 총 메모리.스레드 3: 작업 단계 – 작업 메모리 – 총 메모리. 각 스레드는 총 메모리 종류에서 작업 메모리로 읽은 다음에 작업 단계에서 공유 데이터를 조작하고 수정된 데이터를 작업 메모리로 업데이트한 다음에 총 메모리로 업데이트한다.

메서드1:validate:작업 메모리용 – 총 메모리


수식 공유 변수, 데이터 가시성 유지, 적용 범위: 읽기만 하고 수정하지 않습니다.의미: 다중 루틴이 공유 데이터에 접근할 때 읽기만 하고 수정하지 않았을 때validate를 사용할 수 있습니다.
공유 데이터 앞에volatile 수식만 추가하면 라인 동기화를 실현할 수 있다.

방법 2, 3:synchronized 동기화 방법과 동기화 블록


이 두 가지 방식 모두synchronized 키워드를 사용해야 한다.synchronized: , 。는 라인 안이 순서대로 실행되고 라인 사이가 무작위라는 뜻이다.프로세스: 모든 대상에'잠금 표지'가 있습니다. 이 대상의 한 라인이 이 대상의 어떤synchronized 데이터에 접근할 때 이 대상의 모든synchronized에 의해 수식된 데이터는 잠겨집니다('잠금 표지'가 현재 라인에 가져갔기 때문). 현재 라인이 접근하려는synchronized 데이터에 접근할 때만 현재 라인이'잠금 표지'를 방출합니다.이렇게 해야만 같은 대상의 다른 라인이synchronized 데이터에 접근할 수 있다.
synchronized 키워드는 같은 대상의 여러 라인을 사용하는데, 어느 순간에 그 중의 한 라인만 이 대상의 synchronized 데이터에 접근할 수 있도록 합니다.그래서 가능한 한 공유 데이터를 조작하는 코드 블록에만 synchronized 자물쇠를 넣으면 일반적으로 동기화 블록을 사용하는데 자물쇠의 내용이 적고 비용이 적다.

메서드4: 잠금 ReentrantLock 다시 입력


링크:다시 잠금:ReentrantLock 상세 설명 링크:스레드 스케줄링의 ReentrantLock 다중 스레드 순서로 작업 수행
ReentrantLock (): ReentrantLock 실례를 만듭니다. ReentrantLock () 는 공평한 자물쇠를 만들 수 있는 구조 방법도 있지만 프로그램 운영 효율을 대폭 낮출 수 있기 때문에 사용을 권장하지 않습니다.
lock() :   
unlock() :   

주: Lock 대상과 synchronized 키워드에 대한 선택: a. 둘 다 사용하지 않는 것이 좋습니다. 자바를 사용하세요.util.concurrent 패키지가 제공하는 메커니즘은 사용자가 자물쇠와 관련된 모든 코드를 처리하는 데 도움을 줄 수 있습니다.b. 만약synchronized 키워드가 사용자의 요구를 충족시킬 수 있다면synchronized를 사용하십시오. 코드를 간소화할 수 있기 때문입니다. c. 더 높은 기능이 필요하면ReentrantLock류를 사용하십시오. 이때 자물쇠를 제때에 풀어야 합니다. 그렇지 않으면 자물쇠가 사라집니다. 보통finally 코드에서 자물쇠를 풀어줍니다.
public static ReentrantLock lock = new ReentrantLock();
  @Override
    public void run() {
        for (int j = 0; j < 10000; j++) {
            lock.lock();  //  
            //lock.lock(); ①
            try {
                i++;
            } finally {
                lock.unlock(); //  
                //lock.unlock();②
            }
        }
    }

주의: 수동으로 재입구 자물쇠를 풀어야 합니다

방법5: 국부 변수로 라인 동기화 실현(비저지형)


국부 변수를 사용하여 스레드 동기화를 실현한다.'공간으로 시간을 바꾸는 방법'을 사용하고 앞에서 사용한'시간으로 공간을 바꾸는 방법'과 달리ThreadLocal: 주: ThreadLocal과 동기화 메커니즘. a.ThreadLocal과 동기화 메커니즘은 다중 스레드에서 같은 변수의 방문 충돌 문제를 해결하기 위한 것이다.
문제외: 루틴의 방출 잠금 중점 내용wait(): 한 루틴을 대기 상태에 놓고 가지고 있는 대상의lock를 방출합니다.
sleep (): 실행 중인 라인을 수면 상태로 만드는 정적 방법입니다. 이 방법을 사용하면 InterruptedException 이상을 포착할 수 있습니다.notify (): 대기 상태의 라인을 깨웁니다. 이 방법을 호출할 때 대기 상태의 라인을 정확하게 깨울 수 없습니다. JVM에서 어떤 라인을 깨울지, 우선순위에 따라 깨울지 확인하십시오.

좋은 웹페이지 즐겨찾기