조건의 기능은 잠금의보다 정확한 제어를 제공하는 것입니다. 조건의 AWAIT () 메소드는 대상의 대상 () 메소드와 동일하며 조건의 신호 () 메소드는 객체의 notify () 메소드와 동일하며 조건의 SignalLall ()은 객체의 notifyall () 메소드와 동일합니다. 차이점은 객체의 대기 (), notify () 및 notifyall () 메소드가 "동기화 된 잠금"(동기화 된 키워드)과 번들로 연결되어 있다는 것입니다. 조건은 "Mutex"/"Share Lock"으로 번들로 연결되어야합니다.
조건 기능 목록
// 현재 스레드가 신호를 받거나 중단 될 때까지 대기합니다. void는 ()를 기다리므로 신호를 받거나 중단되거나 지정된 대기 시간에 도달하기 전에 현재 스레드가 대기 상태로 유지됩니다. 부울이 기다리고 있습니다 (오랜 시간, TimeUnit 단위) // 신호가 수신되거나 중단되거나 지정된 대기 시간에 도달 할 때까지 현재 스레드가 대기 상태에있게됩니다. long awaitnanos (long nanostimeout) // 신호를 수신하기 전에 현재 스레드가 대기 상태에있게됩니다. void awaituninterruptily () // 신호가 수신되거나 중단되거나 지정된 마감일에 도달 할 때까지 현재 스레드가 대기 상태로 유지됩니다. 부울 awaituntil (날짜 마감일) // 대기 실을 깨우십시오. void signal () // 모든 대기 스레드가 깨어납니다. void signalall ()
조건 클래스 사용 예제
조건은 객체 모니터 방법 (대기, 알림 및 알림)을 완전히 다른 객체로 분해하여 이러한 객체를 잠금 구현과 결합하여 각 객체는 여러 대기 세트 (대기 세트)를 제공합니다. 그중에서도 Lock은 동기화 된 메소드 및 명령문의 사용을 대체하며 조건은 객체 모니터 방법의 사용을 대체합니다. 다음은 조건과 함께 구현 된 스레드 커뮤니케이션의 이전에 작성된 예제이며 코드는 다음과 같습니다.
Public Class ThreadTest2 {public static void main (String [] args) {최종 비즈니스 비즈니스 = 새로운 비즈니스 (); 새 스레드 (new Runnable () {@override public void run () {ThreadExecute (Business, "Sub");}}). start (); ThreadExecute (Business, "Main"); } public static void strookexecute (비즈니스 비즈니스, String ThreadType) {for (int i = 0; i <100; i ++) {try {if ( "main".equals (threadType)) {business.main (i); } else {business.sub (i); }} catch (InterruptedException e) {e.printstacktrace (); }}}} 클래스 비즈니스 {private boolean bool = true; 개인 잠금 잠금 = 새로운 재 렌트 링크 (); 개인 조건 조건 = lock.newcondition (); public /*synchronized* / void main (int loop) 던지기 인터럽트 exception {lock.lock (); try {while (bool) {condition.await (); // this.wait (); } for (int i = 0; i <100; i ++) {System.out.println ( " + i +"의 "메인 스레드 seq," + loop의 루프); } bool = true; 조건 .signal (); // this.notify (); } 마침내 {lock.unlock (); }} public /*synchronized* / void sub (int loop) throws interruptedException {lock.lock (); try {while (! bool) {condition.await (); // this.wait (); } for (int i = 0; i <10; i ++) {system.out.println ( " + i +"의 " + i +", " + loop의 루프); } bool = false; 조건 .signal (); // this.notify (); } 마침내 {lock.unlock (); }}} 조건에서 대기 ()을 Await ()로 바꾸고 notify ()를 Signal ()로 바꾸고 notifyall ()을 SignalLall ()로 바꾸십시오. 스레드의 전통적인 통신 방법을 구현할 수 있습니다. 여기서 조건은 잠금에 묶여 있습니다. 잠금을 만들려면 newCondition () 메소드를 사용해야합니다.
이런 식으로 조건은 전통적인 스레드 커뮤니케이션과 다르지 않습니다. 조건의 힘은 여러 스레드간에 다른 조건을 설정할 수 있다는 것입니다. 다음은 설명 할 API의 코드입니다.
class boundedBuffer {final lock lock = new ReintrantLock (); // 잠금 객체 최종 조건 NoteFull = lock.newCondition () ;/ 스레드 조건 최종 조건 쓰기 최종 조건 NOTEMPTY = LOCK.NEWCONDITION (); 레드 스레드 조건 최종 객체 [] items = new Object [100]; // 캐시드 que int putptr/*read/*read the index*/*read the index*/*read. 대기줄*/; public void put (Object x) 던지기 중간 exception {lock.lock (); try {while (count == items.length) // 대기열이 notfull.await ()로 가득 차면 쓰기 항목을 차단하는 경우 [putptr] = x; // if (++ putptr == items.length) putptr = 0; // 쓰기 인덱스가 queue의 마지막 위치에 기록되면 0 +++++++++++++++++++++++++++++++++++++++를 설정합니다. 스레드} 마침내 {lock.unlock (); }} public Object Take () Throws InterruptedException {lock.lock (); Queue가 비어 있지 않은 경우 que (count = await); // 스레드 객체 x = 항목 [takeptr]; // 값을 선택한다면 (++ takeptr == items.length) takeptr = 0; // queue의 마지막 위치를 읽는 경우, 0- 카운트로 설정하면 (// 숫자로 설정); } 마침내 {lock.unlock (); }}} 이것은 다중 스레드 작업 환경의 캐시 영역입니다. 캐시 영역은 두 가지 방법을 제공합니다. Put은 데이터를 저장하고, 테이크는 데이터를 검색하는 것이며, 내부에 캐시 큐가 있습니다. 특정 변수 및 메소드 설명에 대한 코드를 참조하십시오. 이 캐시 영역 클래스에서 구현 한 기능 : 다중 스레드는 데이터를 저장하고 데이터를 검색합니다. 캐시 큐 (우선, 먼저, 그 다음, out)의 최대 캐시 값은 캐시가 100입니다. 여러 스레드는 상호 배타적입니다. 캐시 큐에 저장된 값이 100에 도달하면 쓰기 스레드가 차단되고 읽기 스레드가 깨어납니다. 캐시 큐에 저장된 값이 0이면 읽기 스레드가 차단되고 쓰기 스레드가 깨어납니다. 코드 실행 프로세스의 다음 분석 :
1. 쓰기 스레드가 풋 방법을 실행하고 호출합니다.
2. 수가 100인지 여부를 결정하기 위해, 분명히 100은 없다.
3. 계속해서 값을 실행하고 입금하십시오.
4. 현재 서면 인덱스 위치 ++를 결정한 후, 100과 같 든 쓰기 인덱스 값을 0 및 count+1로 동일하게;
5. 읽기 스레드 차단 대기열 중 하나만 일어나십시오.
6. 읽기 스레드를 실행하고 테이크 메소드를 호출하십시오.
7.…
8. 쓰기 스레드 차단 대기열 중 하나만 일어나십시오.
이것이 여러 조건의 힘입니다. 캐시 큐가 가득 차 있다고 가정하면 차단은 확실히 쓰기 스레드이며, 깨우기는 확실히 읽기 스레드입니다. 반대로, 차단은 확실히 읽기 스레드이며, 깨우기는 분명히 쓰기 스레드입니다. 그렇다면 한 가지 조건 만 있으면 어떻게됩니까? 캐시 큐가 가득 차서이 잠금은 읽기 스레드인지 쓰기 스레드인지 알지 못합니다. 모닝이 읽기 스레드라면 모두가 행복합니다. 모닝이 쓰기 실인 경우 실이 방금 깨어나 다시 막히고 다시 깨어 난 후 많은 시간을 낭비합니다.