第九周课程总结&实验报告(七)
实验任务详情:
完成火车站售票程序的模拟。
要求:
(1)总票数1000张;
(2)10个窗口同时开始卖票;
(3)卖票过程延时1秒钟;
(4)不能出现一票多卖或卖出负数号票的情况。
1.实验源码:
package MYRunnable; import java.util.concurrent.locks.Lock;//导入java.util.concurrent包,其中有接口Lock import java.util.concurrent.locks.ReentrantLock; public class MYRunnable{ public static void main(String[] args){ Ticket t1=new Ticket(); Thread A1=new Thread(t1,"窗口1"); //十个窗口卖票 Thread A2=new Thread(t1,"窗口2"); Thread A3=new Thread(t1,"窗口3"); Thread A4=new Thread(t1,"窗口4"); Thread A5=new Thread(t1,"窗口5"); Thread A6=new Thread(t1,"窗口6"); Thread A7=new Thread(t1,"窗口7"); Thread A8=new Thread(t1,"窗口8"); Thread A9=new Thread(t1,"窗口9"); Thread A10=new Thread(t1,"窗口10"); A1.start(); A2.start(); A3.start(); A4.start(); A5.start(); A6.start(); A7.start(); A8.start(); A9.start(); A10.start(); } } class Ticket implements Runnable{ //实现Runnable接口 private int tickets=1000; Lock lock =new ReentrantLock();//使用接口Lock的对应的实现类ReentrantLock public int getNumbers() { return tickets; } public void setNumbers(int numbers) { this.tickets = numbers; } public void run(){ //覆写run()方法 while(getNumbers()>0){ lock.lock();//手动获取锁 if(getNumbers()>0){ try{ Thread.sleep(100);//卖票中休眠一秒 } catch(Exception e){ e.printStackTrace(); } tickets--; System.out.println(Thread.currentThread().getName()+"卖了一张票,还剩下"+getNumbers()+"张票"); } lock.unlock();//手动释放锁 } } }
2.实验结果截图:
3.实验的过程和问题:
首先这个题目并不难,书上有类似的题目,在上机课上就对照着书写好了代码,运行结果也没有什么问题,十个窗口都在卖票。但是今天用自己电脑运行后发现有时只有窗口一在卖票,有时也会只有前几个窗口在卖票,后来在网上搜索了解决办法,用了同步代码块和同步方法,进行上锁,但是也没有解决问题。后来考虑到上机的电脑可以运行,会不会是cpu核心的问题,运行速度的问题,于是我就把cpu核心数由四个改成一个,成功的让十个窗口同时卖票。但是具体是什么原理并不清楚,可能和cpu速度有关。
课程学习总结:
Java 提供了三种创建线程的方法:
- 通过实现 Runnable 接口;
为了实现 Runnable,一个类只需要执行一个方法调用 run(),声明如下:public void run()
- 通过继承 Thread 类本身;
创建一个新的类,该类继承 Thread 类,然后创建一个该类的实例。继承类必须重写 run() 方法,必须调用 start() 方法才能执行。
- 通过 Callable 和 Future 创建线程。
thread类和runnable接口的区别:
1.实现Runnable接口可以实现资源共享而继承Thread类不能资源共享,也就是实现Runnable接口是多个线程共同完成一个任务,继承Thread类是一个是多个线程分别完成自己的任务。
2.现Runnable接口相对于继承Thread类来说,有如下优势:
(1)适合相同程序的多个线程去处理同一资源的情况。
(2)可以避免由于Java的单继承特性带来的局限。
(3)增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。
使用同步解决问题:
synchronized 方法返回值 方法名称(参数列表){
//方法体
}
java IO
1.使用File操作文件
使用File类可以进行创建或删除文件等常用操作
File.pathSeparator表示“;”,File.Separator表示“"。createNewFile()方法创建文件,mkdir()方法创建文件夹。
学习总结:
本周主要学习了多线程和java IO,作业虽然完成了,但多线程问题中还是有一些不明白,可能和cpu的速度和调用有关,希望以后在实际问题中能更好的理解。