자바 의 동기 화 잠 금 확인

11170 단어 자바 언어
오늘 자바 의 동기 자물쇠 에 대해 말하자면 본 고 는 기본 개념 에 대해 설명 하지 않 고 독자 가 자물쇠 의 기본 용 도 를 이미 알 고 있다 고 가정 합 니까?
잠 금 역할:다 중 스 레 드 가 같은 데 이 터 를 방문 할 때 데이터 에 대한 보 호 를 제공 하여 데이터 가 파괴 되 거나 일치 하지 않 는 것 을 방지 합 니 다.
본 고의 목적:독자 가 자바 의 동기 자물쇠 에 관 한 지식 을 명확 하 게 인식 하고 프로그램 에서 합 리 적 으로 사용 할 수 있 도록 돕는다
동기 자물쇠 로 생산자 소비자 모델 을 실현 하고 계속 내 려 다 볼 것 을 강력 히 건의 하 다.
생산자 소비자 단순 모델 코드 참조:
public class Main{

    List list = new ArrayList();

    public static void main(String[] args) throws Exception {
        Main t = new Main();
        Consumer consumer = t.new Consumer();
        Producer producer = t.new Producer();
        consumer.start();
        producer.start();      
    }

     class Consumer extends Thread{
        @Override
        public void run() {

                while (true) {
                    synchronized (list) {

                        if (list.size() > 0) {
                        //  list        
                            for(int i = 0 ;i < list.size();i++) {
                                list.remove(i);
                                System.out.println("  1 ");
                            }
                        }else{
                        //  list              ,        
                            list.notifyAll();
                            list.wait();
                        }
                    }
                }
        }
    }


    class Producer extends Thread{
        @Override
        public void run() {

                while (true) {
                    synchronized (list) {
                        if (list.size() == 0) {
                            //  list        
                            list.add(1);
                            System.out.println("  1 ");
                        }else{
                            //            ,          
                            list.notifyAll();
                            list.wait();

                        }
                    }
                }
        }
    }

이상 은 생산자 와 소비자 의 간단 한 모델 예시 이다.
전체 프로그램의 사고방식 은 두 개의 라인 을 시작 하 는 것 이다.하 나 는 자원 의 생산자 Producer 이 고,하 나 는 자원 의 소비자 Consumer 이 며,자원 의 용 기 는 list 이다.코드 논 리 는 생산자 가 list 에 자원 이 없다 는 것 을 발견 하면 하 나 를 추가 하고,있 으 면 라인 은 대기 상태 에 들 어가 고,소비 자 는 반대로 있 으 면 소비 하고 없 으 면 기다린다.
위의 절 차 는 우리 가 생각 하 는 방향 에 따라 진행 할 수 있 습 니 다.콘 솔 은 끊임없이 인쇄 하여 1 개,소비 1 개,생산 1 개,소비 1 개 를 생산 합 니 다.
만약 에 위의 모든 줄 코드 의 역할 을 뚜렷하게 이해 할 수 있다 면 동기 자물쇠 의 용법 과 기본 을 파악 할 수 있다 는 것 을 설명 한다.만약 에 아직 잘 모 르 면 위의 코드 와 관련 된 지식 점 을 상세 하 게 분석 하 겠 다.
첫 번 째:하나의 스 레 드 가 list 를 조작 할 때 다른 스 레 드 가 조작 할 수 없 도록 해 야 합 니 다.그렇지 않 으 면 데이터 가 일치 하지 않 는 상황 이 발생 할 수 있 으 므 로 list 에 잠 금 처 리 를 하여 다른 스 레 드 의 변경 을 방지 해 야 합 니 다.
두 번 째:wait(),notify(),notify All()방법 에 대해 간단하게 말 하면 이 몇 가지 방법 은 현재 스 레 드 를 기다 리 고 깨 우 는 방법 입 니 다.Object 류 의 방법 입 니 다.Object 는 모든 종류의 부모 클래스 이기 때문에 모든 대상 에 게 이 방법 이 있 습 니 다.
wait():현재 스 레 드 로 하여 금 이 대상 의 자 물 쇠 를 기다 리 게 합 니 다.그것 은 도대체 누구의 자물쇠 입 니까?호출 된 사람 은 누구의 자 물 쇠 를 가 져 옵 니 다.예 를 들 어 위 에서 list.wait()를 호출 했 습 니 다.이것 은 현재 스 레 드 를 기다 리 게 하 는 것 을 의미 합 니 다.wait()방법 을 호출 하 는 것 은 요구 가 있 습 니 다.현재 스 레 드 는 대상 의 자 물 쇠 를 가 져 야 wait()방법 을 호출 할 수 있 습 니 다.여기 있 는 독자 들 은 약간 어 지 러 울 수 있 습 니 다.자 물 쇠 를 가 져 야 wait()를 호출 할 수 있 습그럼 wait 호출 은 뭘 기다 리 는 거 예요?이것 은 다음 방법 과 관련 이 있 습 니 다.wait()를 호출 하 는 것 은 다른 스 레 드 가 notify()를 호출 하 는 방법 을 기다 리 는 것 입 니 다.
notify():이 방법 은 위의 wait 와 대응 하 는 것 입 니 다.이 자원 을 기다 리 는 스 레 드 를 깨 우 는 것 입 니 다.'아,형제 여,자 물 쇠 를 풀 겠 습 니 다.가 져 가서 사용 하 세 요!'그 다음 에 다른 특정한 스 레 드 는 자 물 쇠 를 가 져 와 서 계속 일 을 하 게 되 었 습 니 다.그리고 notify All 이라는 방법 도 있 습 니 다.역할 은 notify 와 같 습 니 다.jdk 의 설명 문서 에서 뚜렷 한 차이 가 없고 사용 효과 가 똑 같은 것 같 습 니 다.
대상 잠 금,클래스 잠 금,synchronized 동기 화 방법,그리고 synchronized 동기 화 코드 블록 은 도대체 무엇 입 니까?그들 사 이 는 또 어떤 관계 입 니까?
대상 잠 금 및 synchronzied 방법 은 다음 코드 를 보십시오.
// java            ,obj1 obj2         
Object obj1 = new Object();
Object obj2 = new Object();

synchronized 는 대상 의 동기 화 자 물 쇠 를 가 져 오 는 뜻 입 니 다.다음 코드 를 보십시오.
public void test1(){
    synchronized(obj1){
        System.out.println("   ....");
    }
}

위의 코드 는 obj 1 대상 의 자 물 쇠 를 가 져 오 는 것 입 니 다.만약 에 obj 1 대상 의 자물쇠 가 다른 스 레 드 에 의 해 가지 고 있다 면 프로그램 은 synchronzied 에 멈 춰 서 obj 1 의 자 물 쇠 를 가 져 올 때 까지 계속 실 행 됩 니 다.
저희 가 자주 보 는 동기 코드 는 이 렇 습 니 다.
public class Main{
    public synchronized void doInSyn(){
        System.out.println("   .......");
    }
}

스 레 드 는 doInSyn()방법 을 실행 할 때 먼저 현재 대상 의 자 물 쇠 를 가 져 와 야 실행 할 수 있 습 니 다.사실은 아래 와 같은 쓰기 효 과 를 가 집 니 다.
public class Main{
    public void doInSyn(){
        //      this          
        synchronized(this){
            System.out.println("   .......");
        }
    }
}

여기까지 대상 의 자 물 쇠 를 이 해 했 을 거 라 고 믿 지만,때때로 우 리 는 다음 과 같은 문법 을 볼 수 있다
public static synchronized doInSync(){
}

여기 synchronzied 는 현재 대상 의 동기 화 자 물 쇠 를 가 져 와 서 실행 하 는 것 입 니까?물론 답 은 부정 적 이기 때문에 다음 에 우리 가 말 하고 자 하 는 것 은 유형의 자물쇠 이다.이름과 대상 의 자물쇠 가 다 르 지만 사실은 원 리 는 같다.
자바 에서 정적 방법 은 클래스 에 속 하기 때문에 정적 방법의 자물쇠 도 클래스 의 자물쇠 입 니 다.
자바 의 정적 방법 은 클래스 에 속 합 니 다.다음은 코드 를 통 해 설명 하 겠 습 니 다.
public class ClassLockTest extends Thread {

    public static void main(String[] args) {
        ClassLockTest t1 = new ClassLockTest();
        t1.setName("T_One");
        ClassLockTest t2 = new ClassLockTest();
        t2.setName("T_Two");
        t1.start();
        t2.start();
    }

    @Override
    public void run() {
        try {
            print(this.getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static synchronized void print(String threadName){
        int count = 5;
        while(count-- > 0){
            Thread.sleep(100);
            System.out.println(threadName + " "+count);
        }
    }
}

  :
T_One 4
T_One 3
T_One 2
T_One 1
T_One 0
T_Two 4
T_Two 3
T_Two 2
T_Two 1
T_Two 0

두 개의 스 레 드 를 동시에 시작 하여 인쇄 하 는 것 을 볼 수 있 지만 순서 가 전혀 어 지 럽 지 않 습 니 다.정적 동기 화 방법(static synchronized 수식)은 대상 의 자 물 쇠 를 먼저 가 져 온 다음 에 실행 합 니 다.가 져 오지 않 으 면 다른 스 레 드 가 실 행 될 때 까지 기 다 립 니 다.
위의 방법 은 이런 표기 법 과 같다.

public static void print(String threadName) {
    synchronized(ClassLockTest.class){
        int count = 5;
        while(count-- > 0){
            Thread.sleep(100);
            System.out.println(threadName + " "+count);
        }
}

}

좋은 웹페이지 즐겨찾기