现在在学java基础,在看一些马士兵老师的视频,确实通俗易懂。
最近看到线程这一章时,发现运行 消费者和生产者 代码部分时,总会出现先消费 后生产。
源代码如下:
public class ProducerConsumer { public static void main(String[] args) { SyncStack ss = new SyncStack(); Producer p = new Producer(ss); Consumer c = new Consumer(ss); new Thread(p).start(); new Thread(c).start(); } } class WoTou { int id; WoTou(int id) { this.id = id; } public String toString() { return "WoTou : " + id; } } class SyncStack { int index = 0; WoTou[] arrWT = new WoTou[6]; public synchronized void push(WoTou wt) { while(index == arrWT.length) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); arrWT[index] = wt; index ++; } public synchronized WoTou pop() { while(index == 0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); index--; return arrWT[index]; } } class Producer implements Runnable { SyncStack ss = null; Producer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0; i<20; i++) { WoTou wt = new WoTou(i); ss.push(wt); System.out.println("生产了:" + wt); try { Thread.sleep((int)(Math.random() * 200)); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer implements Runnable { SyncStack ss = null; Consumer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0; i<20; i++) { WoTou wt = ss.pop(); System.out.println("消费了: " + wt); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } }
运行结果:
消费了: WoTou : 0
生产了:WoTou : 0
生产了:WoTou : 1
生产了:WoTou : 2
生产了:WoTou : 3
生产了:WoTou : 4
消费了: WoTou : 4
生产了:WoTou : 5
生产了:WoTou : 6
生产了:WoTou : 7
消费了: WoTou : 7
生产了:WoTou : 8
消费了: WoTou : 8
生产了:WoTou : 9
消费了: WoTou : 9
生产了:WoTou : 10
消费了: WoTou : 10
生产了:WoTou : 11
消费了: WoTou : 11
生产了:WoTou : 12
生产了:WoTou : 13
消费了: WoTou : 12
生产了:WoTou : 14
消费了: WoTou : 13
消费了: WoTou : 14
生产了:WoTou : 15
消费了: WoTou : 15
生产了:WoTou : 16
消费了: WoTou : 16
生产了:WoTou : 17
消费了: WoTou : 17
生产了:WoTou : 18
消费了: WoTou : 18
生产了:WoTou : 19
消费了: WoTou : 19
消费了: WoTou : 6
消费了: WoTou : 5
消费了: WoTou : 3
消费了: WoTou : 2
消费了: WoTou : 1
应该是线程出现问题,在push()方法结束后,要打印生产了第几个窝头时,另一线程执行了起来,导致消费在生产之前。
修改代码:把打印部分都放进push()和pop()方法内,同时pop()方法返回类型为void。
代码如下:
public class ProducerConsumer { public static void main(String[] args) { SyncStack ss = new SyncStack(); Producer p = new Producer(ss); Consumer c = new Consumer(ss); new Thread(p).start(); new Thread(c).start(); } } class WoTou { int id; WoTou(int id) { this.id = id; } public String toString() { return "WoTou : " + id; } } class SyncStack { int index = 0; WoTou[] arrWT = new WoTou[6]; public synchronized void push(WoTou wt) { while(index == arrWT.length) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); arrWT[index] = wt; index ++; System.out.println("生产了:" + wt); } public synchronized void pop() { while(index == 0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); index--; System.out.println("消费了: " + arrWT[index]); } } class Producer implements Runnable { SyncStack ss = null; Producer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0; i<20; i++) { WoTou wt = new WoTou(i); ss.push(wt); try { Thread.sleep((int)(Math.random() * 200)); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer implements Runnable { SyncStack ss = null; Consumer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0; i<20; i++) { ss.pop(); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } }
相关推荐
马士兵多线程训练营笔记
马士兵多线程训练营上课笔记
马士兵多线程预习资料.md文件,需要的可以下载,资源还是不错的,md中有代码 很爱很爱你
马士兵j2se源码和ppt马士兵j2se源码和ppt马士兵j2se源码和ppt马士兵j2se源码和ppt马士兵j2se源码和ppt
马士兵老师spring框架学习笔记
马士兵JAVA笔记(全).docx
马士兵oracle笔记,浅显易懂。
jvm java虚拟机 调优 马士兵 笔记 让你对java虚拟机调优有初步的认识
linux 马士兵笔记
马士兵老师mybatis相关学习笔记
马士兵Spring课堂笔记(超级详细版).pdf
马士兵老师HashMap学习笔记
马士兵Shopping项目源代码,马士兵Shopping项目源代码,马士兵Shopping项目源代码,马士兵Shopping项目源代码,
是自己根据马士兵的NewShopping模仿着一步步做的,对项目的界面进行了美化,更加漂亮美观,并对视频中项目一些细节不足的地方进行了一些修正,并添加了部分功能进行完善,但是对于视频中报表和文件上传的功能我并...
马士兵 struts2 操作手册
java 马士兵 网上商城 源代码 可以运行的购物系统
以前学java时候看的马士兵老师的教程,老师讲的较快,有些不适应,自己做些笔记巩固练习,效果还不错,贴出来分析大家把,配图+示例。。。
对多线程高并发编程学习的一个总结,整理了多线程在实际应用中的例子。主要参考了马士兵老师在java高并发编程公开课视频中的例子,并在此基础上进行学习和总结!
马士兵hibernate文档.doc