JAVA 멀티스레드 - 기본 Lock Condition 동시 집합

6044 단어
전편 JAVA 멀티스레드-기초 Synchronized 후편 JAVA 멀티스레드-인터랙티브 컴퓨팅 Future Callable Promise 후편 JAVA 멀티스레드-스레드 탱크-실례 시뮬레이션 화장실 문제
이전 기사와 비교해 볼 때, 이번에는 이전 코드를 개선하고, Lock Condition과 병렬 집합을 사용했다.코드의 양이 약간 줄어들었고 더욱 쉽게 읽을 수 있었다.

이 코드는 전편의 개선판으로, 논리는 전편에 설명이 있어서, 모두가 볼 수 없도록 하기 위해서, 내가 다시 한 번 붙여 보겠다.코드가 더욱 간단해지기 위해 고급 라인 도구를 사용하여 다시 개선할 것입니다.코드의 로직:


1) SProducer가 끊임없이 number를 queue에 생성합니다.2) 캐리어 3개가 queue의number를 끊임없이 꺼낸다.3)queue에 10개의 잉여number가 존재하면 SProducer는 멈춰서서 Carrier가 소비를 좀 한 후에 생산한다.4) Carrier가 queue에number가 없는 것을 발견하면 기다립니다.5) Carrier가 뽑은 숫자의 끝이 4이면 파업이 일어난다.6) Carrier 파업은 Negotiation 라인의 협상을 유발할 수 있다.7) 파업 단계 중 SProducer와 모든 Carrier가 휴업한다.8)Negotiation에서 인출한number의 수위가 3 또는 7인 것을 발견하면 협상에 실패할 수 있다.9) 협상이 성공하면 업무를 회복하고 협상이 실패하면 파산하며 모든 라인이 퇴출된다.
주의: lock을 사용할 때 반드시 주의해야 합니다. lock () 와 unlock () 방법은 반드시 쌍으로 나타나야 합니다.try {}finally {}에 넣는 것이 좋습니다. 그러면 unlock () 방법은 반드시 바뀔 것입니다.만약 unlock () 을 사용하지 않으면return이 되고, 라인이 사라집니다.
package concurrency;

import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Producer extends Thread {
	private final static ArrayBlockingQueue<String> numbers = new ArrayBlockingQueue<String>(10);
    private final static ArrayList<Thread> threads = new ArrayList<Thread>();
    private volatile boolean negotiating  = false;
    private ReentrantLock negotiationLock = new ReentrantLock();
    private Condition negotiationCondition = negotiationLock.newCondition();
    
    private class Negotiation implements Runnable {
        private String number;
        private Negotiation(String number) {
            this.number = number;
        }
        public void run() {
            try {
                System.out.println("Start negotiation...");
                sleep(5000);
                if (number.startsWith("7") || number.startsWith("3")) {
                    System.out.println("Negotiation broken.");
                    for (Thread t : threads) {
                        t.interrupt();
                    }
                    System.out.println("Negotiation broken post handle.");
                    return;
                }
                System.out.println("Negotiation succeeds.");
            } catch (InterruptedException e) {
                System.out.println("Middle man is killed.");
            }
            negotiationLock.lock();
            negotiating = false;
            negotiationCondition.signalAll();
            negotiationLock.unlock();
        }
    }
    
    private class Carrier implements Runnable {
        private String name;
        private Carrier(String name) {
            this.name = name;
        }
        public void run() {
            while(true) {
            	try{
            	negotiationLock.lock();
            	while(negotiating) {
            		try {
            			System.out.println("Carrier ["+name+"] join stricks.");
						negotiationCondition.await();
					} catch (InterruptedException e) {
						System.out.println("Negotiation fails. Carrier [" + name + "] retires.");
                        return;
					}
            	}
            	} finally {
            	negotiationLock.unlock();
            	}
                String number;
				try {
					number = numbers.take();
					System.out.println("Carrier [" + name + "] carries "+ number +" out of List;");
				} catch (InterruptedException e1) {
					 System.out.println("Negotiation fails. Carrier [" + name + "] retires.");
                     return;
				}
                 
                if (number.endsWith("4")) {
                	try {
                	negotiationLock.lock();
                	while (negotiating) {
                	    try {
							negotiationCondition.await();
						} catch (InterruptedException e) {
							System.out.println("Negotiation fails. Carrier [" + name + "] retires.");
	                        return;
						}
                	}
                    negotiating = true;
                    System.out.println("Stricks happen on number:"+number);
                    new Thread(new Negotiation(number)).start();
                	} finally {
                	negotiationLock.unlock();
                	}
                }
            }
        }
    }
    
    public void run() {
        Thread a = new Thread(new Carrier("a"));
        Thread b = new Thread(new Carrier("b"));
        Thread c = new Thread(new Carrier("c"));
        threads.add(this);
        threads.add(a);
        threads.add(b);
        threads.add(c);
        
        a.start();
        b.start();
        c.start();
        
        this.produceNumbers();
        
    }
    
    private void produceNumbers() {
        while (true) {
        	while(negotiating) {
	            negotiationLock.lock();
	            try {
	                System.out.println("Stricking... Producer waiting for negotiation result.");
	                negotiationCondition.await();
	                System.out.println("Negotiation succeeds. Producer happy.");
	            } catch (InterruptedException e) {
	                System.out.println("Negotiation fails. Producer breaks up.");
	                return;
	            } finally {
	            	negotiationLock.unlock();
	            }
        	}
            
            String number = ""+new java.util.Random().nextInt(47);
          
            try {
				numbers.put(number);
				System.out.println("Produce number " + number + " into List;");
			} catch (InterruptedException e) {
				System.out.println("Negotiation fails. Producer breaks up.");
                return;
			}
        }
    }
        
    
    public static void main(String[] args) {
        new Producer().start();
    }
}

좋은 웹페이지 즐겨찾기