Java多线程循环打印ABC 10次,可能是东半球最美解决方案了

Java多线程循环打印ABC 10次

主要考查java对象锁的wait/notify机制的理解。

此处解法在MVC分层以及细粒度锁上做了很多思考,设计方式更加面向对象,核心工作类A、B、C已经最简化和最抽象化。

对于题目的变种比如ABC打印次数增加以及不同打印顺序都有比较好的设计支持,不需要动核心的A、B、C类,灵活性也更强。


package com.dragon.hqw;

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

/**
 * @author [email protected]
 * @date 2016.1.19
 * @desc
 * Java多线程循环打印ABC,9次
 */
public class PrintABC {

//control & lock 机制
	private static final class CountingLock extends ReentrantLock {
		private static final long serialVersionUID = -4489011051093305026L;
		private int mNum = 0;
		private final int total;

		private final Condition a;
		private final Condition b;
		private final Condition c;

		private CountingLock(int total) {
			this.total = total * 3;
			a = this.newCondition();
			b = this.newCondition();
			c = this.newCondition();
		}

		private boolean isA() {
			return mNum % 3 == 0;
		}

		private boolean isB() {
			return mNum % 3 == 1;
		}

		private boolean isC() {
			return mNum % 3 == 2;
		}

		private boolean increase() {
			mNum++;
			if (mNum > total - 3) {
				return true;//任务循环的退出机制
			}
			return false;
		}

		private Condition getA() {
			return a;
		}

		private Condition getB() {
			return b;
		}

		private Condition getC() {
			return c;
		}
	}

	private static final class A extends Thread {

		private CountingLock mCountingLock;

		private A(final CountingLock countingLock) {
			this.mCountingLock = countingLock;
		}

		public void run() {

			while (true) {
				mCountingLock.lock();
				try {
					if (mCountingLock.isA()) {
						printA();
						boolean end = mCountingLock.increase();
						mCountingLock.getA().signal();
						if (end) {
							break;
						}
					} else {
						try {
							mCountingLock.getC().await();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				} finally {
					mCountingLock.unlock();
				}
			}
		}

		private void printA() {
			System.out.print("A \t");
		}
	}

	private static final class B extends Thread {

		private CountingLock mCountingLock;

		private B(final CountingLock countingLock) {
			this.mCountingLock = countingLock;
		}

		@Override
		public void run() {
			while (true) {
				mCountingLock.lock();
				try {
					if (mCountingLock.isB()) {
						printB();
						boolean end = mCountingLock.increase();
						mCountingLock.getB().signal();
						if (end) {
							break;
						}
					} else {
						try {
							mCountingLock.getA().await();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				} finally {
					mCountingLock.unlock();
				}
			}
		}

		private void printB() {
			System.out.print("B \t");
		}
	}

	private static final class C extends Thread {

		private CountingLock mCountingLock;

		private C(final CountingLock countingLock) {
			this.mCountingLock = countingLock;
		}

		@Override
		public void run() {
			while (true) {
				mCountingLock.lock();
				try {
					if (mCountingLock.isC()) {
						printC();
						boolean end = mCountingLock.increase();
						mCountingLock.getC().signal();
						if (end) {
							break;
						}
					} else {
						try {
							mCountingLock.getB().await();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				} finally {
					mCountingLock.unlock();
				}
			}
		}

		private void printC() {
			System.out.print("C \t");
		}
	}

	public static void main(String[] args) {
		CountingLock lock = new CountingLock(9);
		A a = new A(lock);
		B b = new B(lock);
		C c = new C(lock);
		a.start();
		b.start();
		c.start();
	}
}


你可能感兴趣的:(Java多线程循环打印ABC 10次,可能是东半球最美解决方案了)