자바 wait 와 notifyAll 은 간단 한 차단 대기 열 을 실현 합 니 다.

wait,호출 된 스 레 드 를 대기 상태 로 들 어가 게 하고 가지 고 있 는 대상 자 물 쇠 를 풀 어 줍 니 다.(호출 할 때 도 자 물 쇠 를 먼저 가 져 와 야 합 니 다.그렇지 않 으 면 이상 IllegalMonitorStateException 을 던 집 니 다)
notify All,notify 는 이전 대상 이 기다 리 고 있 는 스 레 드 를 깨 웁 니 다.(호출 할 때 도 잠 금 을 가 져 와 야 합 니 다.그렇지 않 으 면 이상 IllegalMonitor State Exception 을 던 집 니 다)
또한 join 방법 을 기록 하고 join 방법 을 호출 하면 현재 스 레 드 를 대기 에 들 어가 게 합 니 다.대기 시간 이 설정 되 어 있 지 않 으 면 다른 스 레 드 가 실 행 될 때 까지 기 다 렸 다가 돌아 갑 니 다(ps:join 방법 을 호출 하면 반드시 다른 스 레 드 를 실행 하 는 것 이 아 닙 니 다.현재 스 레 드 가 대기 에 들 어간 다음 스 레 드 로 전환 합 니 다)

import java.util.concurrent.atomic.AtomicInteger;
/**
 * @author lhd
 */
public class BlockQueue {
	/**
  *       
  */
	private final Object addLock = new Object();
	/**
  *       
  */
	private final Object deleteLock = new Object();
	/**
  *      
  */
	private final Integer size = 30;
	/**
  *     
  */
	private Object[] queue = new Object[size];
	/**
  *      ,  AtomicInteger      int                ,      
  */
	private AtomicInteger count = new AtomicInteger(0);
	/**
  *   
  * @param o   
  */
	public void add(Object o) {
		//     ,wait                ,      
		synchronized (addLock){
			//          ,       
			while (count.get() >= size){
				try {
					addLock.wait();
				}
				catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			//    
			queue[count.get()] = o;
			//  
			int i = count.incrementAndGet();
			//      
			String name = Thread.currentThread().getName();
			System.out.println(name + "     ,    " + i);
		}
		//       ,   notifyAll     
		if (count.get() >= 1){
			//notifyAll、notify         ,       
			synchronized (deleteLock){
				deleteLock.notifyAll();
			}
		}
	}
	/**
  *   
  * @return
  */
	public Object poll(){
		Object o;
		//      ,      
		synchronized (deleteLock){
			//          
			while (count.get() <= 0){
				try {
					deleteLock.wait();
				}
				catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			//    
			o = queue[count.get()];
			//  
			int i = count.decrementAndGet();
			String name = Thread.currentThread().getName();
			System.out.println(name + "     ,    " + i);
		}
		//       ,        
		if (count.get() < size){
			//       
			synchronized (addLock){
				addLock.notifyAll();
			}
		}
		return o;
	}
	/**
  *      
  * @param args
  */
	public static void main(String[] args) {
		BlockQueue blockQueue = new BlockQueue();
		Thread t1 = new Thread(()-> {
			while (true){
				blockQueue.add(new Object());
			}
		}
		);
		Thread t2 = new Thread(()-> {
			while (true){
				blockQueue.add(new Object());
			}
		}
		);
		Thread t3 = new Thread(()-> {
			while (true){
				blockQueue.add(new Object());
			}
		}
		);
		Thread t4 = new Thread(()-> {
			while (true){
				blockQueue.poll();
			}
		}
		);
		Thread t5 = new Thread(()-> {
			while (true){
				blockQueue.poll();
			}
		}
		);
		Thread t6 = new Thread(()-> {
			while (true){
				blockQueue.poll();
			}
		}
		);
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		t5.start();
		t6.start();
	}
}
효과:사실 이 체감 작업 과 인쇄 작업 도 원자 작업 이 아 닙 니 다.

순서대로 스 레 드 인쇄 1,2,3

/**
 * @author lhd
 */
public class JoinTest {


 public static void main(String[] args) throws InterruptedException {
  Thread t1 = new Thread(() -> System.out.println(1));
  Thread t2 = new Thread(()-> System.out.println(2));
  Thread t3 = new Thread(()-> System.out.println(3));

  t1.start();
  t1.join();

  t2.start();
  t2.join();

  t3.start();
  t3.join();
 }
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기