zoukankan      html  css  js  c++  java
  • 35.线程问题

    需求:三个窗口同时售卖50张票

    代码如下:

    //模拟3个窗口同时售票
    class SaleTicket extends Thread{
        //定义票数
        int num = 50;
        public SaleTicket(String name) {
            super(name);
        }
        @Override
        public void run() {
            while (true) {
                if(num>0) {
                    System.out.println(Thread.currentThread().getName()+"买了"+num+"号票");
                    num--;
                }else {
                    System.out.println(Thread.currentThread().getName()+"票卖完了");
                    break;
                }
            }
        }
    }
    
    
    public class Demo5 {
        public static void main(String[] args) {
            SaleTicket sale1 = new SaleTicket("窗口1");
            SaleTicket sale2 = new SaleTicket("窗口2");
            SaleTicket sale3 = new SaleTicket("窗口3");
            sale1.start();
            sale2.start();
            sale3.start();
        }
    }

     

    疑问:怎么每个窗口都卖了50号的票,本来只有50张票,怎么卖出了150张的票呢?

    原因:因为票数是静态的成员变量,静态的成员变量会在每个对象中都会维护一份数据

    解决方案:把票数变成静态的成员变量,共享给三个对象

    代码如下:

    //模拟3个窗口同时售票
    class SaleTicket extends Thread{
        //定义票数
        static int num = 50;
        public SaleTicket(String name) {
            super(name);
        }
        @Override
        public void run() {
            while (true) {
                if(num>0) {
                    System.out.println(Thread.currentThread().getName()+"买了"+num+"号票");
                    num--;
                }else {
                    System.out.println(Thread.currentThread().getName()+"票卖完了");
                    break;
                }
            }
        }
    }
    
    
    public class Demo5 {
        public static void main(String[] args) {
            SaleTicket sale1 = new SaleTicket("窗口1");
            SaleTicket sale2 = new SaleTicket("窗口2");
            SaleTicket sale3 = new SaleTicket("窗口3");
            sale1.start();
            sale2.start();
            sale3.start();
        }
    }

     

    疑问:怎么又把50号票卖了三次呢?难道问题还没解决?

    原因:其实把票数设置成了静态后,确实解决了每个对象都维护一份数据的现象(可以看出只买了50次,而不是150次)

    此图的数据不同,但是原理一样(不要注重细节嘛!!)


    当线程1刚运行到输出语句并输出了卖了多少号票,还没执行num--这个语句的时候,cup被线程3抢夺了

    当线程3执行了一个完整的循环(输出了,num也减一了)后,cup被线程1抢了,并执行了num--

    者时候cup被线程3抢夺了,并输出了语句.....(后面原理差不多)

    总结出现线程安全问题的原因:

            1.存在至少2个线程共享一个资源

            2.存在至少2句语句操作同一个共享资源

    下一篇笔录会讲解如何解决此问题

  • 相关阅读:
    [工作代码]dom4j解析实例
    dom4j解析xml报错:Nested exception: org.xml.sax.SAXParseException: White space is required between the processing instruction target and data.
    小米蓝牙耳机使用说明书
    猎豹浏览器(chrome内核)屏蔽视频广告
    [转载]python的常用代码模板
    [转载]存储过程
    存储过程格式及实例
    springboot(十八):解决跨域问题
    springboot(十八):CORS方式实现跨域
    springboot(十七):过滤器(Filter)和拦截器(Interceptor)
  • 原文地址:https://www.cnblogs.com/zjdbk/p/8967375.html
Copyright © 2011-2022 走看看