《Java技术》第十次作业
(一)学习总结
1.用思维导图对本周的学习内容进行总结

2.阅读程序,采用实现Runnable接口的方式用多线程实现这个小游戏。下面给出主线程类,补充Tortoise线程类和Hare线程类。
-
修改后的程序:
public class TortoiseHareRace { public static void main(String[] args) { System.out.println("龟兔赛跑开始了..."); Tortoise tortoise = new Tortoise(10); Hare hare = new Hare(10); Thread tortoiseThread = new Thread(tortoise); Thread hareThread = new Thread(hare); tortoiseThread.start(); hareThread.start(); } } public class Tortoise implements Runnable { private int step; private int step1 = 0; public Tortoise(int i) { //构造函数 this.step = i; } public void run() { //重写run方法 boolean flag = true; while (flag) { if (step1 < this.step) { try { Thread.sleep(300); step1++; System.out.println("小乌龟爬了" + step1 + "步"); } catch (InterruptedException e) { e.printStackTrace(); } } else { System.out.println("小乌龟到达终点!"); flag = false; } } } } public class Hare implements Runnable { private int step; private int step2 = 0; public Hare(int i) { this.step = i; } public void run() { boolean[] flags = {true,false}; boolean flag = true; while (flag) { if (step2 < this.step) { try { Thread.sleep(300); boolean isHareSleep = flags[((int)(Math.random()*10))%2]; if (isHareSleep) {// 兔子睡觉 System.out.println("小兔子睡觉了"); } else { step2 = step2 + 2; System.out.println("小兔子蹦了" + step2 + "下"); } } catch (InterruptedException e) { e.printStackTrace(); } } else { System.out.println("小兔子到达终点!"); flag = false; } } } }
3.下面的程序是模拟了生产者——消费者问题,生产者生产10个数,消费者依次消费10个数,运行程序,看结果是否正常?存在什么问题?说明原因。使用synchronized, wait, notify解决程序出现的问题。写出修改的部分程序即可。
-
运行结果:
![]()
-
原因:
因为生产者产生数的方法中没有调用消费者取走的方法,调用方法的同时运用wait,notify -
修改后的程序:
class Consumer implements Runnable { private Clerk clerk; public Consumer(Clerk clerk) { this.clerk = clerk; } public void run() { System.out.println("消费者开始消耗整数......"); // 消耗10个整数 for (int i = 1; i <= 10; i++) { try { // 等待随机时间 Thread.sleep((int) (Math.random() * 3000)); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Producer implements Runnable { private Clerk clerk; public Producer(Clerk clerk) { this.clerk = clerk; } public void run() { System.out.println("生产者开始生产整数......"); // 生产1到10的整数 for (int product = 1; product <= 10; product++) { try { Thread.sleep((int) Math.random() * 3000); } catch (InterruptedException e) { e.printStackTrace(); } clerk.setProduct(product); // 将产品交给店员 } } } class Clerk { private int product = -1; // -1 表示目前没有产品 private int p; // 这个方法由生产者呼叫 public synchronized void setProduct(int product) { if (this.product != -1) { try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.product = product; p = this.product; System.out.printf("生产者设定 (%d)%n", this.product); getProduct(); this.product = -1; super.notify(); } // 这个方法由消费者呼叫 public synchronized int getProduct() { if (this.product == -1) { try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.printf("消费者取走 (%d)%n", p); this.product = -1; super.notify(); return this.product; } } public class ProductTest { public static void main(String[] args) { Clerk clerk = new Clerk(); Thread consumerThread = new Thread(new Consumer(clerk)); Thread producerThread = new Thread(new Producer(clerk)); consumerThread.start(); producerThread.start(); } } -
修改后程序运行结果:
消费者开始消耗整数...... 生产者开始生产整数...... 生产者设定 (1) 消费者取走 (1) 生产者设定 (2) 消费者取走 (2) 生产者设定 (3) 消费者取走 (3) 生产者设定 (4) 消费者取走 (4) 生产者设定 (5) 消费者取走 (5) 生产者设定 (6) 消费者取走 (6) 生产者设定 (7) 消费者取走 (7) 生产者设定 (8) 消费者取走 (8) 生产者设定 (9) 消费者取走 (9) 生产者设定 (10) 消费者取走 (10)
4.其他总结
-
synchronized, wait, notify具体使用技巧:
http://blog.sina.com.cn/s/blog_4eaff65601000bvf.html
(二)实验总结
1. 模拟三个老师同时分发80分作业,每个老师相当于一个线程。
-
程序设计思路:
三个老师同时发80份作业,首先是资源共享,所以要继承Runnable接口,在test类中每个老师作为一个线程调用start()。 -
类图结构:
![]()
2. 模拟一个银行存款的程序。假设有两个储户都去银行往同一个账户进行存款,一次存100,每人存三次。要求储户每存一次钱,账户余额增加100,并在控制台输出当前账户的余额。
-
程序设计思路:
三个类,用户类,银行类,测试类,银行类中存款余额和返回余额,我将存钱方法写入run方法。在测试类中调用start()。因为有数据共享,所以要继承Runnable接口。 -
类图结构:
![]()
-
问题1:
同学指出我余额money用的是static,这样money就成了全局变量,谁都可以访问,这样不对。 -
问题2:
![]()
-
原因:
我把对象声明在run()方法里面了。 -
解决方案:
Bank b = new Bank(); public synchronized void run(){ int num = 3; while(num >0){ num--; try{ Thread.sleep(300); }catch(InterruptedException e){} b.deposits(); System.out.println( Thread.currentThread().getName()+"存款100元\n"+b.print()); } }
(三)代码托管
- 码云commit历史截图(代码地址)

(四)学习进度条
| 代码行数(新增/累积) | 学习时间(新增/累积) | 本周学习内容 | |
|---|---|---|---|
| 目标 | 5000行 | 300小时 | |
| 第2-4周 | 400/400 | 40/40 | 课上讲的String类用法,温习了很多遍,写程序的时候也查了不少资料,对各种类型做了总结。 |
| 第5周 | 450/850 | 45/85 | 复习了上课讲的知识,并且在完成学习总结的时候查阅了很多资料去了。解单列设计模式 等知识点,还将ppt上的程序打了一遍。 |
| 第6周 | 300/1250 | 35/120 | 从课外书上更深的了解了抽象类,同学介绍的网站上面了解了类图的画法。 |
| 第7周 | 400/1250 | 40/160 | 对接口了解不够深,请同学给我讲了讲,翻资料找了些关于接口的程序去敲。 |
| 第10周 | 400/1650 | 40/200 | 在网上找了许多关于set\list\map接口的实例和用法详解。去学习去理解 |
| 第12周 | 350/2000 | 40/240 | 学习并掌握了本次学习内容 |
| 第13周 | 150/2150 | 30/270 | 学习并掌握了本次学习内容,学习了数据库的应用。 |
| 第14周 | 50/2200 | 4/274 | 学习并掌握了本次学习内容。 |
| 第15周 | 60/2260 | 4/278 | 学习并掌握了本次学习内容。 |




浙公网安备 33010602011771号