1.车票
属性:起始站、终点站、票价
2.系统12306
属性:集合
方法
3.窗口window 多线程
package system12306;
/**
* @author liuxian
*/
public class Ticket {
//User类 Ticket类 没有任何逻辑
//只是包含一些基本属性 每一个对象 小容器
//一个对象 包含很多属性 增强可读性 类名 属性名 属性类型不一致
//POJO JavaBean
private String start;//起始站名
private String end;//终点站名
private Float price;
public Ticket(String start, String end, Float price) {
this.start = start;
this.end = end;
this.price = price;
}
public Ticket(){}
//为了让打印输出时变得方便 打印一个对象就可以了
//重写toString方法
@Override
public String toString(){
StringBuilder builder=new StringBuilder("[");
builder.append(this.start);
builder.append("-->");
builder.append(this.end);
builder.append(":");
builder.append(this.price);
builder.append("]");
return builder.toString();
}
public String getStart() {
return start;
}
public void setStart(String start) {
this.start = start;
}
public String getEnd() {
return end;
}
public void setEnd(String end) {
this.end = end;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
}
package system12306;
import java.util.Vector;
/**
* @author liuxian
*/
public class System12306 {
//设计一个单例模式
private System12306(){}
private static System12306 sys=new System12306();
public static System12306 getInstance(){
return sys;
}
//属性 集合ArrayList Vector synchronized Stack(先进后出)
private Vector<Ticket> tickets=new Vector<>();
//当前系统创建后给tickets集合赋值
{
for (int i=10;i<100;i++){
tickets.add(new Ticket("北京"+i,"深圳"+i,(i%5+5)*25F));
}
}
//设计一个方法 从集合内获取一张火车票
public Ticket getTicket(){
try {
return tickets.remove(0);
} catch (Exception e) {
return null;
}
}
}
package system12306;
/**
* @author liuxian
*/
public class Window extends Thread{
private String windowName;//窗口的名字
public Window(String windowName){
this.windowName=windowName;
}
@Override
public void run() {
this.sellTicket();
}
public void sellTicket(){
while (true){
System12306 sys=System12306.getInstance();
Ticket ticket = sys.getTicket();//Vector
if (ticket==null){
System.out.println("对不起"+windowName+"窗口车票已售完");
break;
}
System.out.println("从"+windowName+"售出:"+ticket);
}
}
}
package system12306;
/**
* @author liuxian
*/
public class TestMain {
public static void main(String[] args) {
Window w1=new Window("北京北站");
Window w2=new Window("北京西站");
Window w3=new Window("北京南站");
w1.start();
w2.start();
w3.start();
}
}


利用Vector集合 集合本身就是线程安全
1.如何切换线程的不同状态
sleep(); start(); run(); setPriority();
wait(); notify(); notifyAll();
2.如果在设计中没有集合,我们自己想要控制线程安全
Synchronized关键字
3.sleep方法和wait方法的区别
sleep方法属于Thread类,静态方法,唤醒不需要别人,不会释放锁。
wait方法数据Object类,访问对象的其他线程等待,需要其他对线下调用notify唤醒,等待后后会释放锁。
4.死锁的解决办法
礼让---->产生时间差
不要让产生对象公用的问题
思考题—>拓展
字节型文件输入流
FileInputStream
read() read(byte[] ) close() available()
skip(long count)
文件 100字节 5个线程对象 同时读
1从头–20 2跳过20读–40 3跳过40–60
思考题:微信抢红包例子
发送红包 5块钱 10个红包 随机(保证10个人都有 至少0.01) 集合里
多个线程 抢红包
计时器/定时器---->线程运用
java.util包 Timer类
package testtimer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TestTimer {
//属性 集合 存储所有人的电话号--账号
private ArrayList<String> userBox=new ArrayList<String>();
{
userBox.add("a");
userBox.add("b");
userBox.add("c");
userBox.add("d");
}
//设计一个方法 做点坏事儿 垃圾短信
//每隔一段时间 发送一些数据
public void test() throws ParseException {
System.out.println("预备,开始");
Timer timer=new Timer();//启动一个小线程 做记录 每隔时间
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date firstTime = sdf.parse("2022-06-29 12:44:00");
timer.schedule(new TimerTask() {
@Override
public void run() {
for (int i=0;i<userBox.size();i++){
System.out.println("给"+userBox.get(i)+"发送了一条消息:【先生很帅!】");
}
System.out.println("做了点坏事儿 真开心~~~");
}
}, firstTime, 3000);
}
public static void main(String[] args) {
TestTimer tt=new TestTimer();
try {
tt.test();
} catch (ParseException e) {
e.printStackTrace();
}
}
}