麻烦老师帮忙看一下为什么不会被唤醒?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | public class j41ThreadCommunication { public static void main(String[] args){ Num num = new Num(); Producer p = new Producer(num); Consumer c = new Consumer(num); Thread ta = new Thread(p, "ta" ); Thread tb = new Thread(c, "tb" ); ta.start(); tb.start(); } //wait()中断方法执行,使线程等待 //notify()唤醒处于等待的某一个线程,使其结束等待, //notifyAll()唤醒所有处于等待的线程。 } class Num{ private int a = 0 ; boolean flag = false ; public void setA( int a){ this .a = a; } public int getA(){ return a; } public boolean isFlag() { return flag; } public void setFlag( boolean flag) { this .flag = flag; } } class Producer implements Runnable{ Num num; public Producer(Num num){ this .num = num; } @Override public synchronized void run(){ int i = 0 ; while (i < 20 ){ System.out.println( "s1" +num.isFlag()); if (num.isFlag()){ try { System.out.println( "1sg" ); this .wait(); } catch (InterruptedException e) { e.printStackTrace(); } } int a = num.getA(); System.out.print( "sa:" +a); num.setA(++a); i++; System.out.println( "生产" +i+ "a:" +num.getA()); num.setFlag( true ); System.out.println( "s2" +num.isFlag()); this .notifyAll(); System.out.println( "激活消费" ); } } } class Consumer implements Runnable{ Num num; public Consumer(Num num){ this .num = num; } @Override public synchronized void run(){ int i = 0 ; while (i < 20 ){ System.out.println( "x1" +num.isFlag()); if (!num.isFlag()){ try { this .wait(); } catch (InterruptedException e) { e.printStackTrace(); } } int a = num.getA(); System.out.print( "xa:" +a); num.setA(--a); i++; System.out.println( "消费" +i+ "a:" +num.getA()); num.setFlag( false ); System.out.println( "x2" +num.isFlag()); this .notifyAll(); System.out.println( "激活生产" ); } } } |
0
收起
正在回答 回答被采纳积分+1
5回答
qq_AnAvenue_0
2019-07-21 15:40:54
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | public class j41ThreadCommunication { public static void main(String[] args){ Num num = new Num(); Producer p = new Producer(num); Consumer c = new Consumer(num); Thread ta = new Thread(p, "ta" ); Thread tb = new Thread(c, "tb" ); ta.start(); tb.start(); } } class Num{ private int a = 0 ; boolean flag = false ; public void setA( int a){ this .a = a; } public int getA(){ return a; } public boolean isFlag() { return flag; } public void setFlag( boolean flag) { this .flag = flag; } } class Producer implements Runnable{ Num num; public Producer(Num num){ this .num = num; } @Override public void run(){ int i = 0 ; while (i < 20 ){ System.out.println( "s1" +num.isFlag()); if (num.isFlag()){ synchronized (num){ try { System.out.println( "1sg" ); num.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } int a = num.getA(); System.out.print( "sa:" +a); num.setA(++a); i++; System.out.println( "生产" +i+ "a:" +num.getA()); num.setFlag( true ); //System.out.println("s2"+num.isFlag()); synchronized (num){ num.notifyAll(); } System.out.println( "激活消费" ); } } } class Consumer implements Runnable{ Num num; public Consumer(Num num){ this .num = num; } @Override public void run(){ int i = 0 ; while (i < 20 ){ System.out.println( "x1" +num.isFlag()); if (!num.isFlag()){ synchronized (num){ try { num.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } int a = num.getA(); System.out.print( "xa:" +a); num.setA(--a); i++; System.out.println( "消费" +i+ "a:" +num.getA()); num.setFlag( false ); //System.out.println("x2"+num.isFlag()); synchronized (num){ num.notifyAll(); } System.out.println( "激活生产" ); } } } |
该代码可得到正确结果
好帮手慕阿莹
2019-07-20 19:15:49
同学你好,同学不应该在生产者和消费着中进行wait(),而是在Num中wait()并唤醒。
在生产者和消费着中,应只是去调用他们的Num对象的set和get方法,
应该把synchronized加在 Num中的set和get方法上。无论是生产还是消费,都应该在Num去做,而Producer和Consumer 只是模拟调用方法。是否可以去生产还是消费,应该由Num去把控。
所以,老师对同学的代码做了如下修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | public class j41ThreadCommunication { public static void main(String[] args){ Num num = new Num(); Producer p = new Producer(num); Consumer c = new Consumer(num); Thread ta = new Thread(p, "ta"); Thread tb = new Thread(c, "tb"); ta.start(); tb.start(); } //wait()中断方法执行,使线程等待 //notify()唤醒处于等待的某一个线程,使其结束等待, //notifyAll()唤醒所有处于等待的线程。 } class Num{ private int a = 0; boolean flag = false; public synchronized void setA(int a){ if(flag) { try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } this.a=a; System.out.println("生成a的值"+a); this.flag = true; this.notifyAll(); } public synchronized int getA(){ if(!flag) { try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("消费a的值"+a); flag =false; this.notifyAll(); return a; } } class Producer implements Runnable{ Num num; public Producer(Num num){ this.num = num; } @Override public void run(){ int i =0; while (true) { num.setA(i); i++; try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } class Consumer implements Runnable{ Num num; public Consumer(Num num){ this.num = num; } @Override public void run(){ while (true) { System.out.println(num.getA()); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } |
建议同学可以再回顾一下本节课程 呦。
如果我的回答解决了你的疑惑,请采纳!祝学习愉快!
1. Java 零基础入门
- 参与学习 人
- 提交作业 3802 份
- 解答问题 11489 个
本阶段带你迈入Java世界,学习Java必备基础知识,基础语法、面向对象思想以及常用工具类的使用。
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧