1.一个多线程实例:
描述:某个火车售票系统,有多个窗口,但是票只在同一个系统中存有:
设计思路: 只存在一个系统:
设计细节: 使用单例设计模式确保多窗口公用一个对象,
使用Vector集合框架保证线程的并发的安全性;
多个窗口卖票,使用多线程模拟多个窗口,在run方法中采用组合的方式调用System 类的sellTicket()方法。
代码如下:
//Ticket 实体类 public class Ticket { //起始站,终点,价格 // 只有一些属性,一个对象包含很多属性,增强可读性 //JavaBean , POJO String start; String end; Float price; //大写,包装类 public Ticket(String start, String end, Float price) { this.start = start; this.end = end; this.price = price; } public Ticket() { } public String getStart() { return start; } public String getEnd() { return end; } public Float getPrice() { return price; } public void setStart(String start) { this.start = start; } public void setEnd(String end) { this.end = end; } public void setPrice(Float price) { this.price = price; } //重写toString 方法,为了打印对象方便 public String toString(){ StringBuilder sb=new StringBuilder(); sb.append(this.start).append("->").append(this.end).append(" 价格").append(this.price); return new String(sb); } } //SystemTest类 public class SystemTest { //只有一个系统: 设计单例模式 private SystemTest(){ } private static SystemTest st=new SystemTest(); //静态: 保证唯一性 public static SystemTest getInstance(){ //静态方法:通过类名可以调用 return st; } //属性 ,集合 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; //没有票的情况 } } } //窗口 Windows类 public class Window extends Thread{ String windowName; public Window(String windowName){ this.windowName=windowName; } @Override public void run() { //卖票 sellTicket(); } public void sellTicket(){ while(true){ SystemTest st=SystemTest.getInstance(); //获得单例对象 Ticket t=st.getTicket(); //从Vector集合中获取票 if(t==null){ System.out.println(windowName+"窗口票已卖完"); break; } System.out.println(windowName+"售出: "+t); } } } //TestMain 测试主类 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(); } }
2.轮流打印ABCABCABC.......10次:
采用synchronized给对象上锁的方式,使得每次访问对象方法的线程不能同时进行,得一个一个来。
扫描二维码关注公众号,回复:
7254975 查看本文章
具体:synchronized(Object){ }
//Test类 即就是 要执行打印的类 //轮流上锁 //线程类跑起来就是一条线程 public class Test implements Runnable{ private String name; // eg: "A" private Object pre; //oa,ob,oc三个对象之间前后循环 private Object self; //自己 public Test(String name, Object pre, Object self) { this.name = name; this.pre = pre; this.self = self; } //每个线程有每个线程的run方法。 @Override public void run() { int count = 10; //倒计时 打印10次 while (count > 0) { synchronized (pre) { synchronized (self) { System.out.print(name); //锁的代码块 count--; self.notify(); } try { pre.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } // @Override // public void run() { // synchronized (pre){ // synchronized (self){ //此处锁的是while的循环体 // //先写自身逻辑在考虑上锁问题 // int count =10; // while(count>0){ // System.out.println(name+count); // count--; // self.notify(); // } // } // try { // pre.wait(); // } catch (InterruptedException e) { // e.printStackTrace(); // } // } // } } //测试主类: public class Main { public static void main(String[] args) throws InterruptedException { Object oa=new Object(); Object ob=new Object(); Object oc=new Object(); new Thread(new Test("A",oc,oa)).start(); Thread.sleep(1000); new Thread(new Test("B",oa,ob)).start(); Thread.sleep(1000); new Thread(new Test("C",ob,oc)).start(); Thread.sleep(1000); } }
3.模拟哲学家进食的问题:
lk