从网易的一道多线程笔试题学习wait与notify来控制线程同步
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从网易的一道多线程笔试题学习wait与notify来控制线程同步相关的知识,希望对你有一定的参考价值。
题目 : 有三个线程分别打印A、B、C,请用多线程编程实现,在屏幕上循环打印10次ABCABC…
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(); } } } } }
Exception in thread "pool-1-thread-2" Exception in thread "pool-1-thread-3" java.lang.IllegalMonitorStateException at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Unknown Source) at my.thread.test.PrintThreadExample$PrintRunnable.run(PrintThreadExample.java:72) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) java.lang.IllegalMonitorStateException at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Unknown Source) at my.thread.test.PrintThreadExample$PrintRunnable.run(PrintThreadExample.java:72) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
如果注释掉synchronized (letterPrinter) 则会抛出IllegalMonitorStateException异常,查了一下文档,如下:
如果当前线程不是对象监视器的拥有者的话则会抛出IllegalMonitorStateException异常。也就是当需要调用一个对象的wait方法的时候,首先需要获取这个对象,否则会出现问题。Statck上一个回答解释了原因,如下:
这个例子说明了加锁的原因之一是为了操作原子性,以免引起死锁的问题
以上是关于从网易的一道多线程笔试题学习wait与notify来控制线程同步的主要内容,如果未能解决你的问题,请参考以下文章