1. CAS 및 동기화 된 적용 시나리오
1. 리소스 경쟁이 적은 상황의 경우 스레드 차단 및 웨이크 업 스위칭에 동기화 된 동기화 잠금을 사용하고 사용자 상태 커널 간의 스위치 작업은 CPU 리소스의 추가 낭비입니다. CAS는 하드웨어를 기반으로 구현되지만 커널을 입력 할 필요는 없으며 스레드를 전환 할 필요가 없으며 스핀 작동 가능성이 적으므로 성능이 높아질 수 있습니다.
2. 심각한 자원 경쟁의 경우, CAS 스핀의 확률은 상대적으로 높아서 더 많은 CPU 자원을 낭비하고 동기화 된 것보다 덜 효율적입니다. java.util.concurrent.atomic 패키지에서 Atomicinteger 클래스를 취하면 getAndincrement () 메소드가 다음과 같이 구현됩니다.
public final int getAndincrement () {for (;;) {int current = get (); int next = current + 1; if (compareAndset (current, next))을 반환합니다. }}CompareAndset (현재, Next) 메소드가 성공적으로 실행되면 직접 반환됩니다. 스레드 경쟁이 치열하여 성공적으로 실행할 수없는 비교 가제 (현재, 다음) 메소드가 발생하면 CPU가 스레드에 할당 된 시간 슬라이스가 소진되어 효율성이 크게 줄어들 때까지 반복되고 기다릴 것입니다.
2. CAS 오류 사용 시나리오
공개 클래스 Casdemo {Private Final int Thread_num = 1000; 개인 최종 int max_value = 200000000; 개인 atomicinteger casi = 새로운 atomicinteger (0); 개인 int synci = 0; 개인 문자열 path = "/users/pingping/datacenter/books/linux/linux common comments.txt"; public void casadd ()는 중단 된 예시 {long begin = system.currenttimeMillis (); 스레드 [] 스레드 = 새 스레드 [Thread_num]; for (int i = 0; i <thread_num; i ++) {threads [i] = new Thread (new runnable () {public void run () {while (casi.get () <max_value) {casi.getAndincrement ();}}}); 스레드 [i] .start (); } for (int j = 0; } system.out.println ( "CAS 비용 시간 :" + (System.CurrentTimeMillis () - 시작); } public void syncadd ()는 중단 된 결과 {long begin = system.currentTimeMillis (); 스레드 [] 스레드 = 새 스레드 [Thread_num]; for (int i = 0; i <thread_num; i ++) {threads [i] = new 스레드 (new runnable () {public void run () {while (synci <max_value) {synchronized ( "synci") {++ synci;}}}); 스레드 [i] .start (); } for (int j = 0; j <thread_num; j ++) 스레드 [j] .join (); System.out.println ( "동기화 비용 시간 :" + (System.CurrentTimeMillis () - 시작); }}내 듀얼 코어 CPU에서 실행하면 결과는 다음과 같습니다.
다른 스레드에서 CAS 계산을 사용하는 데 소요되는 시간은 동기화 된 것보다 훨씬 많다는 것을 알 수 있습니다. 그 이유는 15 행입니다
14 while (casi.get () <max_value) {15 casi.getandincrement (); 16}작업은 매우 시간이 많이 걸리는 작업입니다. 15 줄이 실행되면 루프가 즉시 입력되고 실행이 계속되어 심각한 스레드 충돌이 발생합니다.
3. CAS 사용 시나리오 향상
위의 문제를 해결하기 위해서는 각 루프의 실행 시간을 더 길게 만들면 스레드 충돌을 크게 줄일 수 있습니다. 다음과 같이 코드를 수정하십시오.
공개 클래스 Casdemo {Private Final int Thread_num = 1000; 개인 최종 int max_value = 1000; 개인 atomicinteger casi = 새로운 atomicinteger (0); 개인 int synci = 0; 개인 문자열 path = "/users/pingping/datacenter/books/linux/linux Common Comments 자세한 설명 .txt"; public void casadd2 ()가 중단 된 결과 {long begin = system.currenttimeMillis (); 스레드 [] 스레드 = 새 스레드 [Thread_num]; for (int i = 0; i <stroom_num; i ++) {threads [i] = new Thread (new runnable () {public void run () {while (casi.get () <max_value) {casi.getAndincrement (); try (inputStream in = new FileInputStream (new File (path))); e) {e.printstacktrace (); 스레드 [i] .start (); } for (int j = 0; j <thread_num; j ++) 스레드 [j] .join (); System.out.println ( "CAS Random 비용 시간 :" + (System.CurrentTimeMillis () - 시작); } public void syncAdd2 ()는 중단 된 결과 {long begin = system.currentTimeMillis (); 스레드 [] 스레드 = 새 스레드 [Thread_num]; for (int i = 0; i <stroom_num; i ++) {threads [i] = new Thread (new runnable () {public void run () {while (synci <max_value) {synchronized ( "synci") {++ synci;} try (inputStream in new fileInputStream (new Pile))) } catch (ioexception e) {e.printstacktrace (); 스레드 [i] .start (); } for (int j = 0; j <thread_num; j ++) 스레드 [j] .join (); System.out.println ( "동기화 비용 시간 :" + (System.CurrentTimeMillis () - 시작); }}while 루프에서는 파일 내용을 읽는 작업이 추가되어 약 40ms가 소요되어 스레드 충돌이 줄어 듭니다. 테스트 결과는 다음과 같습니다.
자원 충돌이 비교적 작을 때 CAS 방법과 동기화 된 동기화 효율은 비슷하다는 것을 알 수 있습니다. CAS가 동기화 된 것보다 더 높은 성능을 달성하지 않는 이유는 무엇입니까?
테스트에 사용 된 JDK는 1.7입니다. JDK1.6부터 시작하여 자물쇠 거친, 잠금 제거, 경량 잠금, 바이어스 잠금, 적응 형 회전 및 기타 기술과 같은 자물쇠 구현에 대한 많은 최적화가 도입되어 잠금 작동의 오버 헤드를 줄입니다. 스핀 잠금의 원리는 CAS 스핀과 유사하며 CAS 스핀보다 훨씬 최적화됩니다. 자세한 내용은 심층적 인 JVM 잠금 메커니즘 1-synchronized를 참조하십시오.
4. 요약
1. CAS를 사용할 때 스레드 충돌이 심각 할 때 프로그램 성능이 크게 줄어 듭니다. CAS는 스레드 충돌이 적은 상황에만 적합합니다.
2. JDK1.6 후에 동기화 된 것이 개선되고 최적화되었다. 동기화 된 기본 구현은 주로 잠금 장치 대기열에 의존합니다. 기본 아이디어는 스핀 후 차단하고 경쟁 전환 후에도 잠금을 위해 계속 경쟁하여 공정성을 약간 희생하지만 높은 처리량을 얻는 것입니다. 스레드 충돌이 적을 때 유사한 성능을 얻을 수 있습니다. 심각한 스레드 충돌이 발생하면 성능이 CAS의 성능보다 훨씬 높습니다.
Java 동시 프로그래밍의 위의 요약 - CAS를 신중하게 사용하는 것은 편집자의 자세한 설명입니다. 나는 그것이 당신에게 참조를 줄 수 있기를 바랍니다. 그리고 당신이 wulin.com을 더 지원할 수 있기를 바랍니다.