Java에서는 동기화 된 키워드 및 잠금 잠금 장치가 자원의 동시 액세스 제어를 실현하는 데 사용됩니다. 고유 한 스레드만이 리소스에 액세스하기 위해 임계 영역에 들어갈 수 있습니다 (읽기 잠금 제외). 이 하위 제어의 주요 목적은 동일한 리소스와 동시에 여러 스레드로 인한 데이터 불일치 문제를 해결하는 것입니다. 다른 시나리오에서 리소스에는 프린터 룸의 여러 프린터와 같은 여러 구덩이와 동시에 사용할 수있는 여러 개의 사본이 동시에 사용할 수 있습니다. 이 경우 Java는 또 다른 동시 액세스 제어 - 자원의 여러 사본에 대한 동시 액세스 제어를 제공하며 오늘날 사용 된 세마포어는 그 중 하나입니다.
Java는 코드 시뮬레이션을 통해 가장 빠른 방식으로 시스템의 잠재적 스레드 안전 문제를 감지 할 수 있습니다. 여기서, 세마포어 (세마포어) 및 CountdownLatch (잠금)는 시뮬레이션을 위해 ExecutorService (스레드 풀)와 함께 사용됩니다. 주요 소개는 다음과 같습니다.
1. 세마포어
이 클래스는 JDK 1.5 이후에 제공됩니다
세마포어는 카운트 기반 세마포어입니다. 이를 기반으로 임계 값을 설정할 수 있습니다. 여러 스레드가 라이센스 신호를 얻기 위해 경쟁하여 자체 응용 프로그램을 작성한 후에 반환합니다. 임계 값을 초과하면 라이센스 신호에 대한 스레드의 응용 프로그램이 차단됩니다. 세마포어는 데이터베이스 연결 풀과 같은 일부 객체 풀, 리소스 풀 등을 제작하는 데 사용할 수 있습니다. 또한 뮤트 잠금 장치와 유사한 메커니즘으로 사용하여 1 카운트의 세마포어를 만들 수 있습니다. 이것을 바이너리 세마포어라고도하며 두 개의 뮤트 상태를 나타냅니다.
2. CountdownLatch
이 클래스는 JDK 1.5 이후에 제공됩니다.
CountdownLatch 클래스는 실행하기 전에 다른 스레드가 해당 작업을 완료 할 때까지 스레드를 기다릴 수 있습니다. 예를 들어, 응용 프로그램의 기본 스레드는 프레임 워크 서비스를 시작하는 스레드가 모든 프레임 워크 서비스를 시작한 후 실행하려고합니다.
CountdownLatch는 카운터를 통해 구현되며 카운터의 초기 값은 스레드 수입니다. 스레드가 자체 작업을 완료 할 때마다 카운터 값이 1만큼 줄어 듭니다. 카운터 값이 0에 도달하면 모든 스레드가 작업을 완료 한 다음 잠금을 기다리는 스레드가 작업 실행을 재개 할 수 있습니다.
아래 그림과 같이 :
위의 두 클래스는 고 동시성을 시뮬레이션하는 효과를 달성하기 위해 조합하여 사용될 수 있습니다. 다음 코드는 예를 제시하는 데 사용됩니다.
패키지 모듈; import java.util.concurrent.countdownlatch; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.concurrent.semaphore; public class countexample {// Public int Clienttal = 5000; // 동시에 동시에 실행 된 스레드 수는 공개 정적 int ThreadTotal = 200; 공개 정적 int count = 0; public static void main (string [] args)은 예외를 {executorService executorService = executor.newCachedThreadPool (); // 반도체, 동시 실의 수를 제어하는 데 사용됩니다. 여기서 최종 세마포어 세마포어 = 새로운 세마포어 (ThreadTotal); // 카운터 최종 CountdownLatch CountdownLatch의 감소를 실현할 수있는 잠금. for (int i = 0; i <clientTotal; i ++) {executorService.execute (() -> {try {// 실행 권한을 얻기 위해이 메소드를 실행하십시오. 실행 허가를 얻기 위해 실행하십시오. 미공개 라이센스의 총 수가 200을 초과하지 않을 때 // 패스를 허용합니다. 그렇지 않으면 라이센스가 획득 될 때까지 스레드 블록과 대기 시간이 semaphore.acke (); CATCH E) {//log.error("Exception ", E.printstacktrace (); } countdownlatch.await (); // 스레드 블록이 있고 잠금 값이 0이 될 때까지 블록이 해제되지 않습니다. ExecutorService.shutdown (); log.info ( "count : {}", count); } private static void add () {count ++; }}위의 방법에 도시 된 바와 같이, 5000 개의 요청이 시뮬레이션되며 200 개의 동시 작업은 동시에 최대 200 개의 동시 작업입니다. 최종 결과를 관찰하고 결과가 각 시간마다 다르고 기대치와 일치하지 않는다는 것을 알 수 있습니다. 결과는 다음과 같습니다.
22 : 18 : 26.449 [Main] Info Modules.countexample -Count : 4997
22 : 18 : 26.449 [Main] Info Modules.countexample -Count : 5000
22 : 18 : 26.449 [Main] Info Modules.countexample -Count : 4995
22 : 18 : 26.449 [Main] Info Modules.countexample -Count : 4998
최종 결론 : 추가 메소드는 스레드 안전이 아닙니다
그런 다음 추가 방법의 스레드 안전을 보장하는 방법은 다음과 같이 추가 메소드를 수정하십시오.
private static void add () {count.incrementandget ();}실행 결과는 다음과 같습니다.
22 : 18 : 26.449 [Main] Info Modules.countexample -Count : 5000
22 : 18 : 26.449 [Main] Info Modules.countexample -Count : 5000
22 : 18 : 26.449 [Main] Info Modules.countexample -Count : 5000
22 : 18 : 26.449 [Main] Info Modules.countexample -Count : 5000
22 : 18 : 26.449 [Main] Info Modules.countexample -Count : 5000
22 : 18 : 26.449 [Main] Info Modules.countexample -Count : 5000
22 : 18 : 26.449 [Main] Info Modules.countexample -Count : 5000
22 : 18 : 26.449 [Main] Info Modules.countexample -Count : 5000
최종 결론 : 수정 된 추가 메소드 스레드-안전
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.