• 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句语句操作同一个共享资源

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

  • 相关阅读:
    洛谷P3003 [USACO10DEC]苹果交货Apple Delivery
    洛谷P1576 最小花费
    洛谷P1821 [USACO07FEB]银牛派对Silver Cow Party
    洛谷P1948 [USACO08JAN]电话线Telephone Lines
    洛谷P3371【模板】单源最短路径
    洛谷P2384最短路
    FirstOfAll
    Proxy模式:管理第三方API
    Abstract Server模式,Adapter模式和Bridge模式
    Observer模式
  • 原文地址:https://www.cnblogs.com/zjdbk/p/8967375.html
Copyright © 2020-2023  润新知