java 다중 루틴의volatile와synchronized 용법 분석

3695 단어 java다중 스레드
본고는 자바 다중 스레드 중의volatile와synchronized 용법을 실례적으로 분석하였다.여러분에게 참고할 수 있도록 나누어 드리겠습니다.구체적인 실현 방법은 다음과 같다.
package com.chzhao;

public class Volatiletest extends Thread {

    private static int count = 0;

    public void run() {
        count++;
    }

    public static void main(String[] args) {
        Thread threads[] = new Thread[10000];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Volatiletest();
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(count);
    }
}

코드가 위와 같이 출력을 기대하는 것은 10000입니다. 그리고count++는 라인이 안전하지 않기 때문에 출력은 항상 10000보다 작을 것입니다.
이 문제를 해결하기 위해volatile 키워드를 추가했습니다.
package com.chzhao;

public class Volatiletest extends Thread {

    private volatile static int count = 0;

    public void run() {
        count++;
    }

    public static void main(String[] args) {
        Thread threads[] = new Thread[10000];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Volatiletest();
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(count);
    }
}

수정한 후에도 10000이 아닌 값을 자주 출력합니다.
synchronized 형식으로 수정되었습니다. 코드는 다음과 같습니다.
package com.chzhao;

public class SynchronizedTest extends Thread {
    private static int count = 0;

    public void run() {
        synchronized (LockClass.lock) {
            count++;
        }
    }

    public static void main(String[] args) {
        Thread threads[] = new Thread[10000];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new SynchronizedTest();
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(count);
    }
}

package com.chzhao;

public class LockClass {
    public static byte[] lock = new byte[0];

}

이렇게 수정하면 출력은 10000입니다.
이렇게 하면volatile라는 키워드가 전혀 쓸모가 없다는 것을 설명합니까?synchronized만 라인 안전을 보장할 수 있습니까?
설명:
자바 언어는 두 가지 내재적인 동기화 메커니즘을 포함하는데 그것이 바로 동기화 블록(또는 방법)과volatile 변수이다.이 두 가지 메커니즘의 제기는 모두 코드 라인의 안전성을 실현하기 위해서이다.그 중에서 Volatile 변수는 동기화가 비교적 나쁘지만 때로는 더욱 간단하고 비용이 적으며 사용도 오류가 발생하기 쉽다.Java 언어의volatile 변수는'정도가 비교적 가벼운 synchronized'로 볼 수 있다.synchronized 블록에 비해volatile 변수에 필요한 인코딩이 적고 실행할 때 비용도 적지만 실현할 수 있는 기능은synchronized의 일부분에 불과하다.
즉, 어떤 경우에는volitile가synchronized보다 사용하기 편리하고, 물론 동기성은 좀 더 떨어진다.
본 논문이 여러분의 자바 프로그램 설계에 도움이 되기를 바랍니다.

좋은 웹페이지 즐겨찾기