JAVA 스레드 4 - 스레드 동기화

4535 단어

1. 라인 안전 문제


다중 스레드 응용에서 다중 스레드는 같은 데이터에 대한 접근을 공유할 수 있으며, 이렇게 하면 데이터를 파괴할 수 있다.같은 파일을 조작하는 경우
한 라인이 공유 데이터의 여러 코드를 조작하는 과정에서 다른 라인이 공유 데이터 연산에 참여하면 라인 안전에 문제가 생길 수 있다.이 문제를 해결하려면 라인 동기화 관련 지식을 습득해야 한다.

2. 라인 안전 해결 방향

여러 조작으로 데이터를 공유하는 코드를 봉인하고 봉인된 코드를 실행하면 다른 코드는 이 코드를 동기화할 수 없으며 현재 코드의 실행이 끝난 후에만 다른 코드는 실행 자격이 있다.

3. 스레드 동기화 - 잠금

synchronized 키워드 동기화 방법이나 코드를 사용합니다.

1. 코드 블록 동기화

동기화 코드 블록을 사용할 때 어느 대상에 동기화를 해야 하는지, 즉 어느 대상의 자물쇠를 가져올지 지정해야 한다.예를 들어, 다음 예제에서는 현재 객체의 잠금을 사용합니다.
public int getX() {
    synchronized (this) {
        return x;
    }
}

2. 동기화 방법

방법에 수식자synchronized를 붙인다.예를 들면 다음과 같습니다.
public synchronized int getX() {
    return x++;
}

동기화 방법의 자물쇠는 현재 종류this입니다.synchronized는 추상적이지 않은 방법만 표시할 수 있고 구성원 변수를 표시할 수 없습니다.

4. 라인 동기화의 전제

여러 개의 라인이 있어야 하고 같은 자물쇠를 사용해야 한다.

5. 동기화 및 잠금 설명


동기화 방법만 있고 변수와 클래스는 동기화할 수 없습니다.
모든 대상에 내장 자물쇠가 하나씩 있다.
클래스의 모든 방법을 동기화할 필요가 없다. 클래스는 동기화와 비동기화 방법을 동시에 가질 수 있다.
만약 한 라인이 대상에게 자물쇠를 얻게 된다면, 다른 라인도 클래스에 들어갈 수 있는 동기화 방법이 없다.
만약에 스레드가 동기화와 비동기화 방법을 가지고 있다면 비동기화 방법은 여러 스레드에 자유롭게 접근할 수 있고 잠금의 제한을 받지 않는다.
라인이 휴면할 때, 그것이 가지고 있는 어떤 자물쇠도 방출되지 않는다.
라인에서 여러 개의 자물쇠 획득하기;
동기 손해의 합병성은 가능한 한 동기 범위를 줄여야 한다.동기화 방법의 자물쇠는 현재 대상의 자물쇠이고 동기화 코드 블록의 자물쇠는 임의의 대상의 자물쇠가 될 수 있다.

6. 동기화 정적 방법

동기화 정적 방법에 사용되는 자물쇠는 이 함수에 속하는 바이트 코드 파일의 대상이며 대상을 사용할 수 있다.getClass () 를 가져옵니다. "현재 클래스 이름.class"로 표시할 수도 있습니다.

7. 라인 동기화의 단점


스레드 동기화는 경쟁 자원에 안전하게 접근하는 동시에 프로그램의 성능에 영향을 미친다.

8. 단일 모드와 관련된 다선정 문제


단일 모드 - 게으름뱅이 모드가 다중 스레드에서 관련된 스레드 문제 해결:
pulbic class Single{
    private static Single single;

    private Single(){
    }

    public static Single getInstance(){
        if(single == null){
            single = new Single();
        }
        return single;
    }
}
이 단락의 코드가 다중 노드 아래에 있으면 다중 노드의 안전 문제가 발생할 수 있다.방법에 동기화 자물쇠를 추가할 수 있다.덮어쓰기는 다음과 같습니다.
pulbic class Single{
    private static Single single;

    private Single(){
    }

    public synchronized static Single getInstance(){
        if(single == null){
            single = new Single();
        }
        return single;
    }
}
그러나 이 방식은 getInstance에 접근할 때마다 자물쇠를 판단하여 성능에 영향을 준다.다음과 같이 최적화할 수 있습니다.
pulbic class Single{
    private static Single single;

    private Single(){
    }

    public static Single getInstance(){
        if(single == null){
            //      this.getClass()   
            synchronized(Single.class){
                if(single == null){
                    single = new Single();
                } 
            }
        }
        return single;
    }
}

자물쇠


1. 자물쇠가 꺼진 이유


일반적으로 두 대상의 자물쇠가 서로 기다리기 때문에 생긴 것이다.

2. 흔한 장면


동기화 플러그인은 자물쇠가 사라지기 쉽다.

3. 사라진 자물쇠를 실현하는 예


DeadLock.java
public class DeadLock implements Runnable{
    private boolean flag;

    pulbic DeadLock(boolean flag){
        this.flag = flag; 
    }

    public void run(){
        if(flag){
            while(true){
                synchronized(MyLock.lockone){
                    System.out.println(Thread.currentThread().getName + ":" + "lockone in if");
                    synchronized(MyLock.locktwo){
                        System.out.println(Thread.currentThread().getName + ":" + "locktwo in if");
                    }
                }
            }
        }else{
            while(true){
                synchronized(MyLock.locktwo){
                    System.out.println(Thread.currentThread().getName + ":" + "locktwo in else");
                    synchronized(MyLock.lockone){
                        System.out.println(Thread.currentThread().getName + ":" + "lockone in else");
                    }
                }
            }
        }
    }
}

MyLock.java
pulbic class MyLock{
    private static final Object lockone = new Object();
    private static finla Object locktwo = new Object();
}

DeadLockDemo.java
public class DeadLockDemo{
        public static void main(String[] args){
        DeadLock r1 = new DeadLock(true);
        DeadLock r2 = new DeadLock(false);

        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);
        t1.start();
        t2.start();
    }
}

좋은 웹페이지 즐겨찾기