模拟售票的两种实现方式

本文介绍了一种基于Java的多线程售票系统实现方法,分别通过继承Thread类和实现Runnable接口的方式,确保多线程环境下售票操作的同步性和一致性。在实现Runnable接口时,通过synchronized(this)实现同步,而继承Thread类时则需要使用静态对象作为锁来避免同步失败。
摘要由CSDN通过智能技术生成

通过继承thread

public class SaleTicket extends Thread{

    static int num = 40;
    static Object object = new Object();
    public SaleTicket(String name){
        super(name);
    }
    public void run(){
        while(true){
            //这里为什么用object对象,下面会讲到
            synchronized(object){
                if(num<=0){
                    System.out.println("票已经卖完");
                    System.exit(1);
                }
                else{
                    System.out.println(Thread.currentThread().getName()+"卖出一张票,还剩"+ --num);
                    try{
                        Thread.sleep(50);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    public static void main(String args[]){
       SaleTicket s1 = new SaleTicket("窗口一");
       SaleTicket s2 = new SaleTicket("窗口二");
       SaleTicket s3 = new SaleTicket("窗口三");
        s1.start();
        s2.start();
        s3.start();
    }
}

通过实现Runnable接口

public class SaleTicket2 implements Runnable {

    private int num = 40;
    public SaleTicket2(){}
    public void run(){
        while(true){
            synchronized(this){
                if(num<=0){
                    System.out.println("票已经卖完");
                    System.exit(0);
                }
                else{
                    System.out.println(Thread.currentThread().getName()+"卖出一张票,还剩"+ --num);
                    try{
                        Thread.sleep(10);
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String args[]){
        SaleTicket2 saleTicket2 = new SaleTicket2();

        Thread t1 = new Thread(saleTicket2,"窗口一");
        Thread t2 = new Thread(saleTicket2,"窗口二");
        Thread t3 = new Thread(saleTicket2,"窗口三");
        t1.start();
        t2.start();
        t3.start();
    }
}

这里解释一下为什么在实现Runnable接口时,可以使用 synchronized (this),而在继承Thread中必须声明静态成员来作为锁的对象。当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。换句话说,在实现Runnable接口时,this指代的是当前类的对象,上文中的saleTicket2 是SaleTicket2的实例对象,在创建多个线程的时候,这些线程公用一个锁的对象(saleTicket2),所以就可以实现同步。而在继承Thread类中,SaleTicket创建了4个线程来模拟窗口,如果用this,系统会认为哪个线程访问,对应线程的SaleTicket的实例就作为锁的对象,导致了会产生4个锁的对象,因此同步失败。所以在要用static修饰一个对象, 来保证锁的对象唯一性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值