多线程实现多窗口售票

多线程实现售票

  • 核心是共享资源的线程安全,因为如果不限制对共享数据的访问,就会导致出现卖同一张票,卖多票的情况。
  • 票数是共享资源,所以对票数进行访问和修改需要进行同步(排队)。
  • 在对票数进行修改的函数上使用synchronized关键字形成同步方法(默认是该类的对象锁)。
  • 这样每次代码运行到该处都会去锁池查看该对象锁是否空闲,空闲就获取锁并进入函数,如果已经有其他线程获取了该锁,就排队等待,等到获得锁的线程运行完毕释放锁才可以进行抢夺。(不过如果没有进行线程休眠,大概率会某一个线程刚释放锁,然后又抢到了锁。)

实现代码:

package thread;
public class ThreadTest implements Runnable {
    int i = 100;//共享资源

    public ThreadTest() {
        this.i=100;
    }

    public ThreadTest(int i) {//构造函数
        this.i = i;
    }

    public void run() {
        while (sale()) {//调用sale方法,同时sale返回值作为循环判断条件
            try {
                Thread.sleep(10);
               /*
				* 这个睡眠是出现效果的关键,因为cpu的抢夺很快,
				* 所以每次线程释放锁的时候都让他休眠一下,
				* 这样其他线程就会立刻抢夺时间片,
				* 这样多窗口售票效果更明显,
				* 哪怕休眠一毫秒效果也很明显*/
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized boolean sale() {//ThreadTest对象锁
        if (i > 0) {
            System.out.println(Thread.currentThread().getName() + "卖出了第" + i + "张票!");
            i--;
            return true;
        } else {
            return false;
        }
    }
}

测试类:

package thread;
public class ThreadMain {
    public static void main(String[] args) {
        ThreadTest w=new ThreadTest(10);
        Thread t1=new Thread(w);
        Thread t2=new Thread(w);
        Thread t3=new Thread(w);
        t1.setName("t1");
        t2.setName("t2");
        t3.setName("t3");
        t1.start();
        t2.start();
        t3.start();
    }
}

效果:

在这里插入图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您讲解一下Java多线程售票窗口实现。假设有3个售票窗口,我们需要实现多线程售票系统,可以采用如下代码实现: ```java public class TicketSeller implements Runnable { private int tickets = 100; // 总票数为100张 @Override public void run() { while (true) { synchronized (this) { // 同步锁,确保多线程访问时线程安全 if (tickets > 0) { try { Thread.sleep(100); // 模拟售票需要的时间 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "售出第" + tickets + "张票"); tickets--; } else { break; } } } } } public class Main { public static void main(String[] args) { TicketSeller ticketSeller = new TicketSeller(); Thread thread1 = new Thread(ticketSeller, "售票窗口1"); Thread thread2 = new Thread(ticketSeller, "售票窗口2"); Thread thread3 = new Thread(ticketSeller, "售票窗口3"); thread1.start(); thread2.start(); thread3.start(); } } ``` 上述代码中,我们定义了一个实现了Runnable接口的TicketSeller类,该类中有一个tickets变量用于存储剩余票数。在run方法中,我们使用了synchronized关键字来确保多线程访问时线程安全,保证在同一时刻只有一个线程能够访问tickets变量。当tickets变量大于0时,线程会售出一张票,并将tickets变量减1,直到所有票都售出为止。 在Main类中,我们创建了3个线程来模拟3个售票窗口,分别调用TicketSeller类的run方法来实现售票。每个线程执行时都会调用run方法,同时访问tickets变量,通过synchronized同步锁来确保多线程访问时线程安全。 这样,我们就实现了一个简单的Java多线程售票窗口程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值