Java实验报告(七)
完成火车站售票程序的模拟。
要求:
- (1)总票数1000张;
- (2)10个窗口同时开始卖票;
- (3)卖票过程延时1秒钟;
- (4)不能出现一票多卖或卖出负数号票的情况。
实验源码:
package com.company;
public class Main {
public static void main (String args[]) {
MyThread my = new MyThread();
new Thread(my, "窗口1").start();
new Thread(my, "窗口2").start();
new Thread(my, "窗口3").start();
new Thread(my, "窗口4").start();
new Thread(my, "窗口5").start();
new Thread(my, "窗口6").start();
new Thread(my, "窗口7").start();
new Thread(my, "窗口8").start();
new Thread(my, "窗口9").start();
new Thread(my, "窗口10").start();
}
}
public class MyThread implements Runnable{
private int ticket = 1000;
public void run() {
for (int i=0;i<1000;i++) {
synchronized(this) {
if(ticket>0) {
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖票:ticket="+ticket);
ticket--;
if(ticket==0) {
System.out.println("票已售完");
}
}
}
}
}
}
实验结果:
本题调试过程碰到问题及解决办法:
原因!!!我居然忘记了写继承!!!!
内容总结:
一、实现自定义线程类
- 1,定义实现类实现Runnable接口
- 2,重写run方法
- 3,创建Thread类对象,将Runnable接口的子类对象作为参数传递给Thread类的构造函数
- 4,调用Thread类的start方法开启线程
二、线程同步
- 同步代码块 :有synchronized关键字修饰的语句块
- 同步代码块中的锁对象可以是任意的对象(但多个线程时,要使用同一个锁对象才能够保证线程安全)
- 同步方法:有synchronized关键字修饰的方法
- 同步方法中的锁对象固定是this
- 静态同步方法:在方法声明上加上static synchronized
- 静态同步方法中的锁对象是类名.class
- 当synchronized修饰一个static方法时,多线程下获取的是类锁,Calss锁可以对类的所有实例起作用
- 当synchronized修饰一个非static方法时,多线程下获取的是对象锁(即类的实例对象)
三、受阻塞和等待休眠
- 受阻塞:线程具有执行资格,没有CPU时间
- 等待和休眠:线程放弃执行资格
- sleep和wait区别:
- sleep是Thread类的方法 自己睡 到时间自己就醒了 sleep休眠时 不释放锁
- wait是Object类方法 等待后 得notify唤醒 wait等待时 释放锁
四、线程中断
- 1.stop()方法,在一个线程对象上调用stop()方法时,线程占用的锁被强制释放,极易导致数据的不一致性或者带锁无限休眠
- 2.interupt()方法,使用等待/通知机制或者给那个线程一个中断信号, 让它自己决定该怎么办