有三个线程分别打印A、B、C, 请用多线程编程实现,在屏幕上循环打印10次ABCABC… java
这是一个比较经常使用的关于线程的考题,通常出如今应届生的校园招聘试卷上。编程
本文给出以下四种解决方法:多线程
/** * @author wangmengjun * */ public class SyncObj { private char letter = 'A'; public void nextLetter() { switch (letter) { case 'A': letter = 'B'; break; case 'B': letter = 'C'; break; case 'C': letter = 'A'; break; default: break; } } public char getLetter() { return letter; } }
/** * @author wangmengjun * */ public class PrintLetterRunnable implements Runnable { private SyncObj syncObj; private char letter; public PrintLetterRunnable(SyncObj syncObj, char letter) { this.syncObj = syncObj; this.letter = letter; } public void run() { for (int i = 0; i < 10; i++) { synchronized (syncObj) { /** * 若是当前线程的字符和同步对象的字符不一致,则当前线程一直等待 */ while (letter != syncObj.getLetter()) { try { syncObj.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 输出当前线程的字符 */ System.out.print(letter); /** * 改变同步对象的letter值 */ syncObj.nextLetter(); /** * 通知其它全部等待线程 */ syncObj.notifyAll(); } } } }
public class Main { public static void main(String[] args) { SyncObj syncObj = new SyncObj(); Thread threadA = new Thread(new PrintLetterRunnable(syncObj, 'A')); Thread threadB = new Thread(new PrintLetterRunnable(syncObj, 'B')); Thread threadC = new Thread(new PrintLetterRunnable(syncObj, 'C')); threadA.start(); threadB.start(); threadC.start(); } }
ABCABCABCABCABCABCABCABCABCABC
JDK 1.5 引入J.U.C包以后,也给咱们提供了更多实现多线程程序的选择: Condition, 原子类AtomicInteger以及Semaphore等。 ui
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; 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'; 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) { e.printStackTrace(); } } System.out.print("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) { e.printStackTrace(); } } /** * 打印信息B */ System.out.print("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) { e.printStackTrace(); } } /** * 打印信息C */ System.out.print("C"); /** * 将当前线程值置为A 并经过ThreadA来执行 */ currentThreadName = 'A'; conditionA.signal(); } finally { lock.unlock(); } } } } }
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) { e.printStackTrace(); } System.out.print("A"); semaphoresB.release(); } } } private class RunnableB implements Runnable { public void run() { for (int i = 0; i < 10; i++) { try { semaphoresB.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.print("B"); semaphoresC.release(); } } } private class RunnableC implements Runnable { public void run() { for (int i = 0; i < 10; i++) { try { semaphoresC.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.print("C"); semaphoresA.release(); } } } }
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.print("A"); sycValue.getAndIncrement(); } } } } private class RunnableB implements Runnable { public void run() { while (sycValue.get() < MAX_SYC_VALUE) { if (sycValue.get() % 3 == 1) { System.out.print("B"); sycValue.getAndIncrement(); } } } } private class RunnableC implements Runnable { public void run() { while (sycValue.get() < MAX_SYC_VALUE) { if (sycValue.get() % 3 == 2) { System.out.print("C"); sycValue.getAndIncrement(); } } } } }
有三个线程分别打印A、B、C, 请用多线程编程实现,在屏幕上循环打印10次ABCABC… this
如上题目解答的方法有多种,本文只给出了几种比较经常使用的解法。atom
掌握本文提供的几个方法,那么,相似的题目按照这个思路,也是能够解决的。spa
如:线程
一个线程打印 1~52,另外一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z。 code
再如:对象
有四个线程一、二、三、4。线程1的功能就是输出A,线程2的功能就是输出B,以此类推......... 如今有四个文件file1,file2,file3, file4。初始都为空。
现要让四个文件呈以下格式: file1:A B C D A B.... file2:B C D A B C.... file3:C D A B C D.... file4:D A B C D A....
这些题目都是类似相通的,有兴趣的朋友能够本身编写一下试试。