java第十次作业
(一)学习总结
1 . 用思维导图对java多线程的学习内容进行总结。
2 . 下面是一个单线程实现的龟兔赛跑游戏。
public class TortoiseHareRace {
public static void main(String[] args) {
int totalStep = 10;
int tortoiseStep = 0;
int hareStep = 0;
boolean[] flags = {true,false};
System.out.println("龟兔赛跑开始了...");
while(tortoiseStep < totalStep && hareStep < totalStep){
tortoiseStep++;
System.out.println("乌龟跑了"+tortoiseStep+"步...");
boolean isHareSleep = flags[((int)(Math.random()*10))%2];
if(isHareSleep){
System.out.println("兔子睡着了zzzz");
}else{
hareStep += 2;
System.out.println("兔子跑了"+hareStep+"步...");
}
}
}
}
阅读程序,采用实现Runnable接口的方式用多线程实现这个小游戏。下面给出主线程类,补充Tortoise线程类和Hare线程类。
public class TortoiseHareRace {
public static void main(String[] args) {
Tortoise tortoise = new Tortoise(10);
Hare hare = new Hare(10);
Thread tortoiseThread = new Thread(tortoise);
Thread hareThread = new Thread(hare);
tortoiseThread.start();
hareThread.start();
}
}
完善后的代码:
class Tortoise implements Runnable {
private int totalStep;
private int tortoiseStep = 0;
public Tortoise(int totalStep) {
this.totalStep = totalStep;
}
public void run() {
running();
}
private synchronized void running() {
System.out.println("龟兔赛跑开始了...");
while (tortoiseStep < totalStep) {
tortoiseStep++;
System.out.println("乌龟跑了" + tortoiseStep + "步...");
}
}
}
class Hare implements Runnable {
private int totalStep;
private int hareStep = 0;
public Hare(int totalStep) {
this.totalStep = totalStep;
}
private synchronized void running() {
boolean[] flags = { true, false };
while (hareStep < totalStep) {
boolean isHareSleep = flags[((int) (Math.random() * 10)) % 2];
if (isHareSleep) {
System.out.println("兔子睡着了zzzz");
} else {
hareStep += 2;
System.out.println("兔子跑了" + hareStep + "步...");
}
}
}
public void run() {
running();
}
}
public class Test {
public static void main(String[] args) {
Tortoise tortoise = new Tortoise(10);
Hare hare = new Hare(10);
Thread tortoiseThread = new Thread(tortoise);
Thread hareThread = new Thread(hare);
tortoiseThread.start();
hareThread.start();
}
}
运行截图:
3 . 下面的程序是模拟了生产者——消费者问题,生产者生产10个数,消费者依次消费10个数,运行程序,看结果是否正常?存在什么问题?说明原因。使用synchronized, 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();
}
clerk.getProduct();// 从店员处取走整数
}
}
}
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); // 将产品交给店员
}
}
}
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();
}
}
class Clerk {
private int product = -1; // -1 表示目前没有产品
// 这个方法由生产者呼叫
public void setProduct(int product) {
this.product = product;
System.out.printf("生产者设定 (%d)%n", this.product);
}
// 这个方法由消费者呼叫
public int getProduct() {
int p = this.product;
System.out.printf("消费者取走 (%d)%n", this.product);
return p;
}
}
修改hou后dai ma:
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();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.product = -1;
super.notify();
}
// 这个方法由消费者呼叫
public synchronized int getProduct() {
if (this.product == -1) {
try {
super.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("消费者取走 (%d)%n", p);
this.product = -1;
super.notify();
return this.product;
}
}
(二)实验总结
实验内容:
实验内容:
1.宠物商店:在实验八的基础上,增加一个功能,用文件保存每日的交易信息记录。
2.完成文件复制操作,在程序运行后,提示输入源文件路径和目标文件路径。
问题1:数据进行记录时重复
原因:将写入数据的代码放入了循环内
错误代码:
//获取所有购买数据
public ArrayList<Buy> queryAllBuyData(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
ArrayList<Buy> list = new ArrayList<Buy>();
try{
conn = JDBCUtils.getConnection(1);
stmt = conn.createStatement();
String sql = "select 编号,类型,价格 from buy";
rs = stmt.executeQuery(sql);
while(rs.next()){
Buy thisbuy = new Buy();
thisbuy.setNumber(rs.getString("编号"));
thisbuy.setKind(rs.getString("类型"));
thisbuy.setPrice(rs.getDouble("价格"));
list.add(thisbuy);
SellPet pet = new SellPet(thisbuy.getNumber(),thisbuy.getKind(),thisbuy.getPrice());
FileUtils.savePets(pet); //将本次数据保存到本地文件
}
return list;
}catch(Exception e ){
e.printStackTrace();
}finally{
JDBCUtils.close(conn);
}
return null;
}
修改后代码:
//添加购买数据
public boolean addBuy(Buy buy){
Connection conn = null;
PreparedStatement pstmt = null;
boolean result=false;
try{
conn = JDBCUtils.getConnection(1);
String sql = "insert into buy (编号,类型,价格) values (?,?,?)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1,buy.getNumber());
pstmt.setString(2,buy.getKind());
pstmt.setDouble(3,buy.getPrice());
int num = pstmt.executeUpdate();
if(num > 0){
result = true;
SellPet pet = new SellPet(buy.getNumber(),buy.getKind(),buy.getPrice());
FileUtils.savePets(pet); //将本次数据保存到本地文件
}
}catch(Exception e ){
e.printStackTrace();
}finally{
JDBCUtils.close(conn);
}
return result;
}
修改后修改后运行结果:
消费者开始消耗整数......
生产者开始生产整数......
生产者设定 (1)
消费者取走 (1)
生产者设定 (2)
消费者取走 (2)
生产者设定 (3)
消费者取走 (3)
生产者设定 (4)
消费者取走 (4)
生产者设定 (5)
消费者取走 (5)
生产者设定 (6)
消费者取走 (6)
生产者设定 (7)
消费者取走 (7)
生产者设定 (8)
消费者取走 (8)
生产者设定 (9)
消费者取走 (9)
生产者设定 (10)
消费者取走 (10)
(二)实验总结
实验内容:
1.模拟三个老师同时分发80分作业,每个老师相当于一个线程。
程序设计思路:创建一个分发作业类,继承Runnable接口,实现线程分发作业功能,在主类中完成功能。
2.模拟一个银行存款的程序。假设有两个储户都去银行往同一个账户进行存款,一次存100,每人存三次。要求储户每存一次钱,账户余额增加100,并在控制台输出当前账户的余额。
程序设计思路:创建银行类(Bank),继承Runnable接口,实现线程存款功能;创建用户类(User),包含存款功能;
(三)代码托管
- 码云commit历史截图