자바 - BlockingQueue 사용

6554 단어 BlockingQueue
매번 오 랜 만 에 블 로그 에 뭐라고 쓰 고 바쁘다 고 하 세 요. 이것 은 자신 에 게 핑 계 를 대 는 것 입 니 다. 사실은 게 으 릅 니까?아...
최근 프로젝트 에 서 는 로그 파일 에서 파 라 메 터 를 가 져 온 다음 서로 다른 API 를 호출 하여 결 과 를 비교 해 야 합 니 다.하지만 어떤 방식 이 좋 을 지 몰라 jdk 의 매 뉴 얼 을 찾 아 보 니 BlockingQueue 라 는 좋 은 물건 을 발견 했다.
BlockingQueue 에 대한 소 개 는 관심 있 으 시 면 직접 보 세 요.http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/LinkedBlockingQueue.html
 
수 요 는 간단 합 니 다. Queue 에 파 라 메 터 를 넣 고 다음 전략 으로 소비 하 는 것 입 니 다.처음에는 서로 다른 스 레 드 를 통 해 대기 열 에 데 이 터 를 저장 한 다음 다음 서비스 에 BlockingQueue 의 대상 으로 돌아 갑 니 다. 다음 정책 은 대기 열 에서 소비 합 니 다. code 는 다음 과 같 습 니 다.
@SuppressWarnings("rawtypes")
	@Override
	public BlockingQueue getTxtLogContent(String path) {
		File file = new File(path);
		BufferedReader reader = null;
		String tempStr = null;
		final BlockingQueue queue = new LinkedBlockingQueue();
		try {
			reader = new BufferedReader(new FileReader(file));
			while ((tempStr = reader.readLine()) != null) {
				final InputOutputPrameters parameter = new InputOutputPrameters();
				String[] list = tempStr.split(";");
				if (list != null && list.length > 0) {
					parameter.setInputParamters(list[0]);
					parameter.setOutputParameters(list[1]);
				}
				new Thread(){
					@SuppressWarnings("unchecked")
					public void run(){
						try {	
							Thread.sleep((long)(Math.random()*100));
							log.info("      !");
							queue.put(parameter);
							log.info("      ,       " + queue.size() +"    !    :"+ parameter.getInputParamters() + ";
:" + parameter.getOutputParameters()); } catch (Exception e) { log.error(" :" + e); } } }.start(); } reader.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (reader != null) { try { reader.close(); } catch (Exception e) { e.printStackTrace(); } } } return queue; }

그러나 실제 실행 할 때 로그 가 비교적 크기 때문에 다음 전략 은 1hour 또는 더 긴 시간 을 기 다 려 야 처리 할 수 있 습 니 다. 이것 은 요구 에 부합 되 지 않 습 니 다. 그래서 최적화 되 었 습 니 다. BlockingQueue 를 전체 static 로 바 꾼 다음 전략 은 이 대기 열 에 값 이 있 는 지, 값 이 있 으 면 소비 하 는 지 직접 감시 할 수 있 습 니 다.값 이 없 으 면 스 레 드 대기 나 시간 초과 등 다른 처 리 를 막 습 니 다.
개 선 된 code:
1. 새 대기 열 클래스:
public class ParameterQueue extends LinkedBlockingQueue<InputOutputPrameters> {

	/** 
	*@Fields serialVersionUID: 
	*/
	private static final long serialVersionUID = 6032356446145302484L;
	
	private static BlockingQueue<InputOutputPrameters> queue = new LinkedBlockingQueue<InputOutputPrameters>();

	/**
	 * @Fields log:     
	 */
	private static final Logger log = LoggerFactory
			.getLogger(ParameterQueue.class);
	
	/** 
	 *          
	 * @Method:getParameter
	 * @Description:          
	 * @return         
	*/
	public static InputOutputPrameters getParameter(){
		InputOutputPrameters result = null;
		try {
			result  = (InputOutputPrameters)queue.take();
		} catch (Exception e) {
			log.error("      ,    :" + e);
		}
		return result;
	}
	
	/** 
	 *        
	 * @Method:getQueueSize
	 * @Description:         
	 * @return   
	*/
	public static Integer getQueueSize() {
		return queue.size();
	}
	
	/** 
	 *          
	 * @Method:putParameter
	 * @Description:          
	 * @param parameter       
	*/
	public static void putParameter(InputOutputPrameters parameter) {
		try {
			queue.put(parameter);
		} catch (Exception e) {
			log.error("      ,    :" + e);
		}
	}
}

2. 파일 을 읽 을 때 이 대기 열 을 직접 조작 하여 대기 열 에 put 값 을 넣 습 니 다. 다음 정책 은 이 대기 열 에서 get 값 을 얻 습 니 다. put 의 code 는 다음 과 같 습 니 다.
public void getSource(String path) {
		try {
			File file = new File(path);
			BufferedReader reader = null;
			String tempStr = null;
			try {
				reader = new BufferedReader(new FileReader(file));
				while ((tempStr = reader.readLine()) != null) {
					final InputOutputPrameters parameter = new InputOutputPrameters();
					String[] list = tempStr.split(";");
					if (list != null && list.length > 0) {
						parameter.setInputParamters(list[0]);
						parameter.setOutputParameters(list[1]);
					}
					putInQueue(parameter);
				}
				reader.close();
			} catch (FileNotFoundException  e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				 if (reader != null) {
					 try {
						 reader.close();
					 } catch (Exception e) {
						 e.printStackTrace();
					 }
				 }
			 }
		} catch (Exception e) {
			log.error("    : " + e);
		}
	}

	/** 
	 *           
	 * @Method:putInQueue
	 * @Description:           
	 * @param parameter       
	*/
	private void putInQueue(final InputOutputPrameters parameter) {
		new Thread(){
			public void run(){
				try {	
					Thread.sleep((long)(Math.random()*100));
					log.info("      !");
					ParameterQueue.putParameter(parameter);
					log.info("      ,       " + ParameterQueue.getQueueSize() +"    !    :"+ parameter.getInputParamters() + ";
:" + parameter.getOutputParameters()); } catch (Exception e) { log.error(" :" + e); } } }.start(); }

  
그래서 이 요 구 는 이 루어 졌 다.이 작은 수 요 를 기록 하면 나중에 찾 아 볼 수 있 습 니 다.
요약 하면 BlockingQueue 는 스 레 드 가 안전 하고 Array BlockingQueue, LinkedBlockingQueue 를 자주 사용 합 니 다.
Array BlockingQueue 는 용량 을 정 해 야 하 며, LinkedBlockingQueue 는 필요 하지 않 습 니 다.
동시에 소비 할 때 take () 는 스 레 드 를 막 을 수 있 습 니 다. 단일 스 레 드 가 달 릴 때 take () 가 도착 하지 않 으 면 전체 스 레 드 가 끊 깁 니 다.
그래서 구체 적 인 환경 수 요 를 보면 take 를 사용 하 는 지 다른 것 을 사용 하 는 지 저 는 보통 poll 을 사용 합 니 다. 시간 초과 시간 을 정할 수 있 기 때 문 입 니 다.
아, 어떻게 썼 는 지 모 르 겠 어 요. 이렇게 하 세 요.

좋은 웹페이지 즐겨찾기