毕向东讲解(摘)—线程售票重复bug

本文通过两个Java多线程卖票实例,探讨了线程安全问题。一是继承Thread类,二是实现Runnable接口的方式创建线程。指出共享变量未同步导致的重复售出问题,并提出解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

没加锁

变量 同时被几个线程修改了

操作共享变量的时候 需要同步

synchronized 或者Lock方法

 

关于static的一个bug:

package day4;

/**

 * 售票的第一种方式:可以将100张票分到四个线程窗口售卖

 * 但是如果是一个线程对象被创建,但是start();了四次的话

 * 程序就会报异常,告诉你xx线程已经被start了,不用重复开启。

 *

 * @author mzy

 *

 */

publicclassTest0Warning{

    publicstaticvoidmain(String[]args){

       MyThreadm0=newMyThread();

       MyThreadm1=newMyThread();

       MyThreadm2=newMyThread();

       MyThreadm3=newMyThread();

       m0.start();

       m1.start();

       m2.start();

       m3.start();

    }

}

 

classMyThreadextendsThread{

    /**

     * 这里如果没有使用static ticket进行修饰的话,结果会使四个窗口都会将

     * 每张票都卖一次;

     */

    // private int ticket =100;

    /**

     * 但是仍然有一个问题,用static修饰的时候,四个线程都会把第100张票卖一次

     */

    privatestaticintticket=100; 

    publicvoidrun(){

       while(ticket>0){

           System.out.println(this.getName()+"卖出第"+ticket+"张票");

           ticket--;

       }

    }

}

 

此程序如果无误的话:应该是每张票被单独卖一次,但是这儿关于线程的调用,四个线程在第一次进入run的时候,都会把第100张票卖一次,其它票无重复状况!

 

 

依旧被卖了四次

package day4;

/**

 * 需求:简单的卖票程序

 * 多窗口同时卖票

 *

 * 创建线程的第二种方式:实现Runnable接口

 *

 * 步骤:

 * 1.定义类实现Runnable接口。

 *

 * 2.覆盖Runnable接口中的run方法。

 *   将要运行的代码存放在该run方法中。

 *

 * 3.通过Thread类建立线程对象。

 *

 * 4.Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。

 *   为什么要将Runnable接口的子类对象传递给Thread的构造函数?

 *     因为自定义的run方法所属的对象是Runnable接口的子类对象。

 *     所以要让线程去指定对象的run方法。

 * @author mzy

 *

 */

publicclassTest1{

    publicstaticvoidmain(String[]args){

       Tickettk=newTicket();

       Threadt1=newThread(tk);

       Threadt2=newThread(tk);

       Threadt3=newThread(tk);

       Threadt4=newThread(tk);

       t1.start();

       t2.start();

       t3.start();

       t4.start();

    }

}

 

classTicketimplements Runnable{

    privateintticket=100;

    @Override

    publicvoidrun(){

       while(ticket>0){

           System.out.println(Thread.currentThread().getName()+""+ticket+"张票已经被卖出");

           ticket--;

       }

    }

   

}

 

 


 

后面运行发现不是只有100是多次重复,其实在其他位置也有重复,比如:969288等这些重复售票的例子,其实和后面的0 -1 -2是一样的,因为现在的CPU计算速率高了,所有对线程安全性要求更高了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值