多线程问题的一些模型

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

猜你喜欢

转载自www.cnblogs.com/xbfchder/p/11504073.html
今日推荐