인터넷의 격렬한 개발로 인해 점점 더 많은 인터넷 회사가 사용자 양의 확장으로 인한 동시 보안 문제에 직면하고 있습니다. 이 기사는 Java 동시성의 몇 가지 일반적인 잠금 메커니즘에 중점을 둡니다.
1. 포지티브 잠금
바이어스 잠금은 JDK1.6에 의해 제안 된 잠금 최적화 메커니즘입니다. 핵심 아이디어는 프로그램이 경쟁하지 않으면 이전에 얻은 스레드 동기화 작업이 취소된다는 것입니다. 즉, 자물쇠가 스레드에 의해 획득되면 바이어스 모드로 들어갑니다. 스레드가 잠금을 다시 요청하면 관련 동기화 작업을 수행 할 필요가 없으므로 작동 시간이 절약됩니다. 다른 스레드가 그 사이에 잠금 요청을하는 경우 잠금은 바이어스 모드를 종료합니다. -XX 사용 :+JVM에서 useBiasedLocking
패키지 jvmproject; import java.util.list; import java.util.vector; public class biased {public static list <integer> numberlist = new vector <integer> (); public static void main (String [] args) {long begin = system.currenttimeMillis (); int count = 0; int startnum = 0; while (count <100000000) {numberlist.add (startnum); startnum+= 2; 카운트 ++; } long end = System.CurrentTimeMillis (); System.out.println (End-Begin); }}벡터를 초기화하고 10 만 명의 정수 객체를 추가 한 다음 시차를 출력하십시오. 이것은 바이어스 잠금의 성능을 테스트하는 데 사용됩니다. ArrayList 대신 벡터를 사용해야하는 이유는 무엇입니까?
ArrayList는 스레드 inSecure이므로 벡터는 스레드 안전입니다. 이것은 충분히 구체적이지 않을 수 있습니다. 소스 코드를 볼 수 있습니다.
벡터의 거의 모든 작업은 Sychronized이고 ArrayList는 그렇지 않으므로 벡터는 스레드 안전합니다.
다음으로 바이어스 잠금 장치의 개구부가 프로그램 성능에 미치는 바이어스 잠금 장치의 개방에 얼마나 많은 영향을 미치는지 테스트 해 봅시다.
JVM 스타트 업 (바이어스 잠금) 매개 변수를 다음과 같이 구성하십시오.
JVM 스타트 업 (닫기 바이어스 잠금) 매개 변수를 다음과 같이 구성하십시오.
완벽한! 바이어스 잠금을 가능하게하는 프로그램의 실행 시간은 상당히 짧습니다. 바이어스 잠금 장치를 활성화하지 않는 것보다 바이어스 잠금을 가능하게하는 특정 장점이 있습니다. 단일 스레드에서 객체를 작동하는 동기화 방법. 실제로, 그것은 또한 이런 식으로 이해 될 수 있습니다. 동기화 메소드가있는 벡터 객체를 작동하는 스레드가 하나만 있으면 벡터의 작업이 ArrayList의 작업으로 변환됩니다.
바이어스 된 잠금 장치는 잠금이 경쟁 할 때 강력한 최적화 효과가 없습니다. 많은 양의 경쟁으로 인해 스레드가 잠금을 고정하는 스레드가 지속적으로 전환되기 때문에 잠금 장치가 바이어스 모드로 유지하기가 어렵 기 때문입니다. 현재 바이어스 잠금을 사용하면 성능 최적화를 달성 할뿐만 아니라 시스템의 성능을 줄일 수 있습니다. 따라서 치열한 경쟁의 경우 사용을 시도 할 수 있습니다.
-xx : -usebiastedlocking 매개 변수는 바이어스 잠금을 비활성화합니다.
2. 가벼운 잠금
바이어스 잠금 장치가 실패하면 Java 가상 머신은 스레드에 경량 잠금을 신청하도록 요청합니다. 가벼운 잠금은 가상 머신 내부에서 구현되며 BasicobjectLock이되는 객체를 사용하여 구현됩니다.이 객체는 Basiclock 객체와 잠금을 고정하는 Java 객체 포인터로 구성됩니다. BasicobjectLock 객체는 Java 스택 프레임에 배치됩니다. Displayed_header 필드는 또한 Basiclock 객체 내부에서 유지되며 객체 헤더의 표시 단어를 백업하는 데 사용됩니다.
스레드가 객체의 잠금 장치를 보유하면 객체의 헤더 표시 단어 정보는 다음과 같습니다.
[ptr | 00] 잠긴
끝의 두 비트는 00이고, 전체 표시 단어는 Basiclock 객체에 대한 포인터입니다. BasicobjectLock 객체가 스레드 스택에 있으므로 포인터는 잠금 장치를 고정하는 스레드 스택 공간을 가리켜 야합니다. 스레드가 객체를 보유하는지 여부를 결정 해야하는 경우, 객체 헤더의 포인터가 현재 스레드의 스택 주소 범위 내에 있는지 여부를 단순히 결정하면됩니다. 동시에, Basiclock 객체의 Displayed_header는 원래 객체의 표시 단어 내용을 백업하고 BasicobjectLock 객체의 OBJ 필드는 잠금을 고정하는 객체의 헤드를 가리 킵니다.
3. 헤비급 잠금
경량 잠금이 실패하면 가상 머신은 헤비급 잠금 장치를 사용합니다. 헤비급 잠금 장치를 사용할 때 물체의 마크 단어는 다음과 같습니다.
[PTR | 10] 모니터
작동 중에 실이 운영 체제 수준에서 일시 중단 될 수 있습니다. 그렇다면 스레드 간 전환 및 통화 비용이 크게 증가합니다.
4. 스핀 잠금
스핀 잠금 장치는 잠금 장치를 얻지 못했을 때 스레드를 매달리지 않고 대신 빈 루프를 실행하도록 전환 할 수 있습니다 (즉, 소위 스핀은 빈 루프 자체를 실행하는 것을 의미합니다). 몇 개의 빈 루프 후에 실이 잠금을 얻을 수 있다면 계속 실행됩니다. 스레드가 여전히 잠금을 얻을 수 없으면 매달려집니다.
스핀 잠금 장치를 사용한 후에는 스레드가 매달릴 가능성이 상대적으로 줄어들고 스레드 실행의 일관성이 비교적 향상됩니다. 따라서 자물쇠와 매우 경쟁하지 않고 매우 짧은 시간을 가진 동시 스레드에 대해서는 긍정적 인 의미가 있습니다. 그러나, 자물쇠와 단일 스레드 잠금 장치와 치열하게 경쟁하는 동시 프로그램의 경우, 스핀 잠금 장치는 종종 스핀 대기 후에 해당 잠금 장치를 얻을 수 없습니다. 이것은 CPU 시간을 낭비 할뿐만 아니라 필연적으로 결국 중단 된 작업을 수행 할뿐만 아니라 시스템 리소스를 낭비합니다.
JDK1.6에서 Java Virtual Machine은 -xx :+Usespinning 매개 변수를 제공하여 스핀 잠금 장치를 활성화하고 -xx : preblockspin 매개 변수를 사용하여 스핀 잠금 대기 시간을 설정합니다.
JDK 1.7에서 시작하여 스핀 잠금의 매개 변수가 취소됩니다. 가상 머신은 더 이상 사용자 구성 스핀 잠금 장치를 지원하지 않습니다. 스핀 잠금 장치는 항상 실행되며 스핀 잠금 장치 수는 가상 시스템에 의해 자동으로 조정됩니다.