자바 키워드 volatile 의 역할

4005 단어 volatile

무엇이 원자 조작 입 니까? 
원자 조작 이란'중단 할 수 없 는 하나 또는 일련의 조작'이다.하나의 조작 이 원자 임 을 확인 하 는 상황 에서 다 중 스 레 드 환경 에서 우 리 는 이 조작 이 외곽 에 성능 이 비 싼 자 물 쇠 를 보호 하기 위해 심지어 원자 조작 을 통 해 우 리 는 상호 배척 자 물 쇠 를 실현 할 수 있다.많은 운영 체제 가 int 형식 에+-값 을 부여 하 는 원자 조작 버 전 을 제공 합 니 다.예 를 들 어 NT 는 Interlocked Exchange 등 API 를 제공 하고 Linux/UNIX 도 atomic 를 제공 합 니 다.set 등 함수. 
 
자바 의 원자 성에 대해 서? 
원자 성 은 long 과 double 을 제외 한 모든 기본 유형 위의'간단 한 조작'에 응용 할 수 있다.long double 이외 의 기본 형식 변 수 를 읽 고 기록 하 는 작업 은 분리 할 수 없 는 작업 으로 작 동 할 수 있 습 니 다.JVM 의 버 전과 다른 문제 로 인해 다른 많은 조작 은 말 하기 어렵다.예 를 들 어++작업 은 C++에서 원자 조작 이지 만 자바 에 서 는 말 하기 어렵다.또 자바 는 AtomicInteger 등 원자 류 를 제공 했다.또 원자 성 으로 병발 을 통제 하 는 것 도 번 거 롭 고 문제 가 생기 기 쉽다. 
 
volatile 원 리 는 무엇 입 니까? 
자바 에서 volatile 키 워드 는 원래'불안정,변화'라 는 뜻 이다. 
volatile 을 사용 하 는 것 과 volatile 을 사용 하지 않 는 것 의 차 이 는 JVM 메모리 메 인 메모리 와 스 레 드 작업 메모리 의 동기 화 에 있 습 니 다.volatile 은 스 레 드 작업 메모리 와 메 인 메모리 사이 에 변 수 를 일치 시 킵 니 다. 
사실은 프로세서 에 저 를 작업 메모리 에 넣 지 말 라 고 했 습 니 다.메 인 메모리 에서 저 를 직접 조작 하 세 요. 
 
다음 재 미 있 는 코드:
package jdk.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestMultiThread implements Runnable {

	private static int i;

	private static volatile Integer vi = 0;

	private static AtomicInteger ai = new AtomicInteger();

	private static Integer si = 0;
	
	private static int ri;

	private static AtomicInteger flag = new AtomicInteger();

	private Lock lock = new ReentrantLock();

	@Override
	public void run() {
		for (int k = 0; k < 200000; k++) {
			i++;
			vi++;
			ai.incrementAndGet();
			synchronized (si) {
				si++;
			}
			lock.lock();
			try {
				ri++;
			} finally {
				lock.unlock();
			}

		}
		flag.incrementAndGet();
	}
	
	public static void main(String[] args) throws InterruptedException {
		TestMultiThread t1 = new TestMultiThread();
		TestMultiThread t2 = new TestMultiThread();
		ExecutorService exec1 = Executors.newCachedThreadPool();
		ExecutorService exec2 = Executors.newCachedThreadPool();
		exec1.execute(t1);
		exec2.execute(t2);
		while (true) {
			if (flag.intValue() == 2) {
				System.out.println("i           		>>>>>" + i);
				System.out.println("volatile vi 		>>>>>" + vi);
				System.out.println("AtomicInteger ai	>>>>>" + ai);
				System.out.println("synchronized si		>>>>>" + si);
				System.out.println("lock ri			>>>>>" + ri);
				exec1.shutdown();
				exec2.shutdown();
				break;
			}
			Thread.sleep(50);
		}
	}

}

 실행 결 과 는 다음 과 같 습 니 다.
i           >>>>>395805
volatile vi >>>>>369741
AtomicInteger ai>>>>>400000
synchronized si>>>>>379400
lock ri>>>>>392087
 
volatile,자바 중++는 원자 조작 이 아니 기 때문에 값 이 정확 하지 않 습 니 다.
synchronized 는 같은 대상 이 아 닙 니 다.si 대상 이 계속 변 하고 있 기 때문에 다음 코드 로 바 꾸 면 정확 합 니 다.
synchronized (Integer.class) {
				si++;
			}

 
lock 잠 금 은 같은 대상 이 아 닙 니 다.static 키워드 수식 을 추가 하고 클래스 변수 로 바 꾸 면 정확 합 니 다.
private static Lock lock = new ReentrantLock();

 
참고:http://blog.csdn.net/luohuacanyue/article/details/7796352

좋은 웹페이지 즐겨찾기