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

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

猜你喜欢

转载自www.cnblogs.com/zjdbk/p/8967375.html