面试题--三个线程循环打印ABC10次的几种解决方法_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 面试题--三个线程循环打印ABC10次的几种解决方法

面试题--三个线程循环打印ABC10次的几种解决方法

 2013/9/29 21:44:18  MouseLearnJava  程序员俱乐部  我要评论(0)
  • 摘要:最近发现公司有份笔试试卷中有道多线程的题目:有三个线程分别打印A、B、C,请用多线程编程实现,在屏幕上循环打印10次ABCABC…这个最早好像是迅雷的面试题目吧,看到了然后就想重温一下这个题目的解决方法。在本文中,给出了五种这个题目的解决方法:使用sleep使用synchronized,wait和notifyAll使用Lock和Condition使用Semaphore使用AtomicInteger下面依次给出每种解决方案的代码:使用sleeppackagemy.thread.test
  • 标签:面试 方法 解决方法 解决 面试题 线程 循环
最近发现公司有份笔试试卷中有道多线程题目有三个线程分别打印A、B、C,请用多线程编程实现,在屏幕上循环打印10次ABCABC…

这个最早好像是迅雷的面试题目吧,看到了然后就想重温一下这个题目的解决方法

在本文中,给出了五种这个题目的解决方法:

  • 使用sleep
  • 使用synchronized, wait和notifyAll
  • 使用Lock 和 Condition
  • 使用Semaphore
  • 使用AtomicInteger


下面依次给出每种解决方案的代码:

使用sleep
class="java">package my.thread.test;

/**
 * @author Eric
 */
public class SleepExample extends Thread {

	private static int currentCount = 0;

	public SleepExample(String name) {
		this.setName(name);
	}

	@Override
	public void run() {
		while (currentCount < 30) {
			switch (currentCount % 3) {
			case 0:
				if ("A".equals(getName())) {
					printAndIncrease();
				}
				break;
			case 1:
				if ("B".equals(getName())) {
					printAndIncrease();
				}
				break;
			case 2:
				if ("C".equals(getName())) {
					printAndIncrease();
				}
				break;
			}
		}

	}

	private void printAndIncrease() {
		print();
		increase();
	}

	private void print() {
		System.out.println(getName());
		if ("C".equals(getName())) {
			System.out.println();
		}
	}

	private void increase() {
		currentCount++;
	}

	public static void main(String[] args) {
		new SleepExample("A").start();
		new SleepExample("B").start();
		new SleepExample("C").start();
	}

}


使用synchronized, wait和notifyAll

package my.thread.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class PrintThreadExample {

	public static void main(String[] args) {
		PrintThreadExample example = new PrintThreadExample();

		LetterPrinter letterPrinter = example.new LetterPrinter();

		ExecutorService service = Executors.newFixedThreadPool(3);

		service.execute(example.new PrintRunnable(letterPrinter, 'A'));
		service.execute(example.new PrintRunnable(letterPrinter, 'B'));
		service.execute(example.new PrintRunnable(letterPrinter, 'C'));

		service.shutdown();
	}

	private class LetterPrinter {
		private char letter = 'A';

		public void print() {
			System.out.println(letter);
			if ('C' == letter) {
				System.out.println();
			}
		}

		public void nextLetter() {
			switch (letter) {
			case 'A':
				letter = 'B';
				break;
			case 'B':
				letter = 'C';
				break;
			case 'C':
				letter = 'A';
				break;
			}
		}

		/**
		 * @return the letter
		 */
		public char getLetter() {
			return letter;
		}

	}

	private class PrintRunnable implements Runnable {

		private LetterPrinter letterPrinter = null;

		private char letter = ' ';

		/**
		 * @param letterPrinter
		 * @param letter
		 */
		public PrintRunnable(LetterPrinter letterPrinter, char letter) {
			super();
			this.letterPrinter = letterPrinter;
			this.letter = letter;
		}

		public void run() {
			for (int i = 0; i < 10; i++) {
				synchronized (letterPrinter) {
					while (letter != letterPrinter.getLetter()) {
						try {
							letterPrinter.wait();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

					letterPrinter.print();
					letterPrinter.nextLetter();
					letterPrinter.notifyAll();

				}
			}

		}

	}

}


JDK 1.5 引入J.U.C包之后,也给我们提供了更多实现多线程程序的选择: Condition, 原子类AtomicInteger以及Semaphore等。


使用Lock 和 Condition

package my.thread.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;

/**
 * 题目:有三个线程分别打印A、B、C,请用多线程编程实现,在屏幕上循环打印10次ABCABC…
 * 
 * 本程序采用Lock和Condition来实现。
 * 
 * @author Eric
 * 
 */
public class ConditionExample {

	private Lock lock = new ReentrantLock();

	private Condition conditionA = lock.newCondition();
	private Condition conditionB = lock.newCondition();
	private Condition conditionC = lock.newCondition();

	/** 当前线程的名字 */
	private char currentThreadName = 'A';

	private static final Logger logger = Logger
			.getLogger("my.thread.test.OrderPrintTest");

	public static void main(String[] args) {

		ConditionExample ce = new ConditionExample();

		ExecutorService service = Executors.newFixedThreadPool(3);
		service.execute(ce.new ThreadA());
		service.execute(ce.new ThreadB());
		service.execute(ce.new ThreadC());

		service.shutdown();
	}

	private class ThreadA implements Runnable {
		public void run() {

			for (int i = 0; i < 10; i++) {
				lock.lock();
				try {
					while (currentThreadName != 'A') {
						try {
							/*
							 * 如果当前线程名字不是A,那么ThreadA就处理等待状态
							 */
							conditionA.await();
						} catch (InterruptedException e) {
							logger.severe(e.getLocalizedMessage());
						}
					}

					/*
					 * 打印出第几遍以及A信息
					 */
					System.out.println(String.format("第%d遍", i + 1));
					System.out.println("A");

					/*
					 * 将当前线程名置为B, 然后通知ThreadB执行
					 */
					currentThreadName = 'B';
					conditionB.signal();

				} finally {
					lock.unlock();
				}
			}
		}

	}

	private class ThreadB implements Runnable {
		public void run() {
			for (int i = 0; i < 10; i++) {
				lock.lock();
				try {
					while (currentThreadName != 'B') {
						try {
							/*
							 * 如果当前线程名字不是B,那么ThreadB就处理等待状态
							 */
							conditionB.await();
						} catch (InterruptedException e) {
							logger.severe(e.getLocalizedMessage());
						}
					}

					/*
					 * 打印信息B
					 */
					System.out.println("B");

					/*
					 * 将当前线程值置为C 并通过ThreadC来执行
					 */
					currentThreadName = 'C';
					conditionC.signal();

				} finally {
					lock.unlock();
				}
			}

		}

	}

	private class ThreadC implements Runnable {

		public void run() {
			for (int i = 0; i < 10; i++) {
				lock.lock();
				try {
					while (currentThreadName != 'C') {
						try {
							/*
							 * 如果当前线程名字不是C,那么ThreadC就处理等待状态
							 */
							conditionC.await();
						} catch (InterruptedException e) {
							logger.severe(e.getLocalizedMessage());
						}
					}

					/*
					 * 打印信息C
					 */
					System.out.println("C");
					System.out.println();

					/*
					 * 将当前线程值置为A 并通过ThreadA来执行
					 */
					currentThreadName = 'A';
					conditionA.signal();

				} finally {
					lock.unlock();
				}

			}
		}
	}
}



使用Semaphore
package my.thread.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemaphoresExample {

	private Semaphore semaphoresA = new Semaphore(1);
	private Semaphore semaphoresB = new Semaphore(0);
	private Semaphore semaphoresC = new Semaphore(0);

	public static void main(String[] args) {
		SemaphoresExample example = new SemaphoresExample();
		ExecutorService service = Executors.newFixedThreadPool(3);

		service.execute(example.new RunnableA());
		service.execute(example.new RunnableB());
		service.execute(example.new RunnableC());

		service.shutdown();
	}

	private class RunnableA implements Runnable {

		public void run() {

			for (int i = 0; i < 10; i++) {
				try {
					semaphoresA.acquire();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(String.format("第%d遍", i + 1));
				System.out.println("A");
				semaphoresB.release();

			}
		}
	}

	private class RunnableB implements Runnable {

		public void run() {

			for (int i = 0; i < 10; i++) {
				try {
					semaphoresB.acquire();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("B");
				semaphoresC.release();
			}

		}
	}

	private class RunnableC implements Runnable {

		public void run() {

			for (int i = 0; i < 10; i++) {
				try {
					semaphoresC.acquire();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("C");
				System.out.println();

				semaphoresA.release();
			}
		}
	}
}



使用AtomicInteger

package my.thread.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerExample {

	private AtomicInteger sycValue = new AtomicInteger(0);

	private static final int MAX_SYC_VALUE = 3 * 10;

	public static void main(String[] args) {
		AtomicIntegerExample example = new AtomicIntegerExample();
		ExecutorService service = Executors.newFixedThreadPool(3);

		service.execute(example.new RunnableA());
		service.execute(example.new RunnableB());
		service.execute(example.new RunnableC());

		service.shutdown();
	}

	private class RunnableA implements Runnable {

		public void run() {

			while (sycValue.get() < MAX_SYC_VALUE) {
				if (sycValue.get() % 3 == 0) {
					System.out.println(String.format("第%d遍",
							sycValue.get() / 3 + 1));
					System.out.println("A");
					sycValue.getAndIncrement();
				}
			}

		}
	}

	private class RunnableB implements Runnable {

		public void run() {

			while (sycValue.get() < MAX_SYC_VALUE) {
				if (sycValue.get() % 3 == 1) {
					System.out.println("B");
					sycValue.getAndIncrement();
				}
			}

		}
	}

	private class RunnableC implements Runnable {

		public void run() {

			while (sycValue.get() < MAX_SYC_VALUE) {
				if (sycValue.get() % 3 == 2) {
					System.out.println("C");
					System.out.println();
					sycValue.getAndIncrement();
				}
			}

		}
	}
}


转载请注明出处http://mouselearnjava.iteye.com/blog/1949228
发表评论
用户名: 匿名