Java - 지정된 순서대로 스레드 실행

며칠 전에 한 친구가 나에게 질문을 하는 김에 쓴 작은 테스트 사례
먼저 결과를 살펴보겠습니다.
A:1
B:2
C:3
A:4
B:5
C:6
A:7
B:8
C:9
A:10
B:11
C:12
A:13
B:14

프로그램 포털:
	public static void main(String[] args) throws Exception {
		ExecutorService es = Executors.newFixedThreadPool(3);
		RunVO vo=new RunVO();
		es.submit(new Run1(vo,null));
		es.submit(new Run2(vo,null));
		es.submit(new Run3(vo,null));
		es.shutdown();
	}

주요 제어 클래스
/**
 * @author MichaelKoo
 * 
 *         2017-6-12
 */
public class RunVO implements Comparable {
	private int count = 1;
	public volatile int order = 1;

	/**
	 * @param count
	 */
	public RunVO(int count) {
		super();
		this.count = count;
	}

	/**
	 * 
	 */
	public RunVO() {
		super();
	}

	public void add() {
		count++;
	}

	/**
	 * @return the count
	 */
	public int getCount() {
		return count;
	}

	public boolean exit() {
		return count == 15;
	}

	public int compareTo(RunVO o) {
		return 0;
	}

	@Override
	public String toString() {
		return "RunVO [count=" + count + ", order=" + order + "]";
	}

}

스레드 1
public class Run1 implements Runnable {

	private RunVO vo;

	/**
	 * @param vo
	 */
	public Run1(RunVO vo, Object next) {
		super();
		this.vo = vo;
	}

	public void run() {
		while (true) {
			synchronized (vo) {
				if (vo.exit()) {
					vo.notifyAll();
					break;
				}
				if (vo.order != 1) {
					try {
						vo.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

				System.out.println("A:" + vo.getCount());

				vo.add();
				vo.order = 2;

				vo.notifyAll();
				try {
					vo.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
public class Run2 implements Runnable {
	private RunVO vo;

	/**
	 * @param vo
	 */
	public Run2(RunVO vo, Object obj) {
		super();
		this.vo = vo;
	}

	public void run() {
		while (true) {
			synchronized (vo) {
				if (vo.exit()) {
					break;
				}
				if (vo.order != 2) {
					try {
						vo.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				System.out.println("B:" + vo.getCount());
				vo.add();
				vo.order = 3;
				vo.notifyAll();
				try {
					vo.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}

		}
	}

}
public class Run3 implements Runnable {

	private RunVO vo;

	/**
	 * @param vo
	 */
	public Run3(RunVO vo, Object obj) {
		super();
		this.vo = vo;
	}

	public void run() {
		while (true) {
			synchronized (vo) {
				if (vo.exit()) {
					vo.notifyAll();
					break;
				}
				if (vo.order != 3) {
					try {
						vo.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				System.out.println("C:" + vo.getCount());
				vo.add();
				vo.order = 1;
				vo.notifyAll();
				try {
					vo.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

이상은 모든 원본 코드,
관건적인 노드는 어떻게 라인의 순서를 제어하는가에 있다. 여기서 사용하는 것은 표지 위치에 따라 표지하는 것이다. 라인은 현재 표지를 판단함으로써 자신의 표지라면 집행하고 반대로 집행하지 않는다.

좋은 웹페이지 즐겨찾기