多线程实现买票问题

实现Runnable接口的方式实现四个线程卖100张火车票的问题

点击查看代码
public class TestTicket {

    public static void main(String[] args) {
        // 启动四个线程卖票。
        TicketThread tt = new TicketThread();//一个线程对象

        new Thread(tt).start();//启动四个线程,操作TicketThread类中的 tickets成员变量
        new Thread(tt).start();
        new Thread(tt).start();
        new Thread(tt).start();
    }
}
class TicketThread implements Runnable {
    // 100张票。
    private Integer tickets = 100;//争用资源..
    @Override
    public void run() {
        while (tickets > 0) {
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (this) {//临界区,当某个线程进入临界区后,其它线程必需等该线程执行完毕后,才有机会进入到该代码块中
                    if(tickets>0) {//此处判断是为了避免出现负数的情况
                        System.out.println(Thread.currentThread() + " is saling   ticket " + tickets);
                        tickets--;
                    }

                }
        }
    }
}
用继承Thread类的方式实现四个线程卖100张火车票的问题---锁的是自定义的线程类
点击查看代码
public class TestTicket2 {
    public static void main(String[] args) {
        // 启动四个线程卖票。
        TicketThread2 t1 = new TicketThread2();
        t1.start();

        TicketThread2 t2 = new TicketThread2();
        t2.start();

        TicketThread2 t3 = new TicketThread2();
        t3.start();

        TicketThread2 t4 = new TicketThread2();
        t4.start();

    }
}

class TicketThread2 extends  Thread {

    private  static  Integer tickets = 100;//静态的变量隶属于类,不属于对象,多个对象共享的。

    @Override
    public void run() {
        while (tickets > 0) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                /*
                    this代表当前对象,我们创建了四个TicketThread2类的对象,this分别代码这四个对象;
                    相当于有四个对象分别上锁和开锁(厕所有四个门),所以不可取;
                    所以我们得为共享静态变量所属于的类上锁,即:TicketThread类上锁。
                */
                synchronized (TicketThread2.class) {
                    if(tickets>0) {//此片判断是为了避免出现负数的情况
                        System.out.println(Thread.currentThread() + "卖出了第" + tickets + "张票");
                        tickets--;
                    }
                }
           }

    }
}
用继承Thread类的方式实现四个线程卖100张火车票的问题---锁的是自定义的火车票类的对象
点击查看代码
public class TestTicket3 {

    public static void main(String[] args) {

        Ticket ticket = new Ticket();
        ticket.tickets = 150;

        // 启动四个线程卖票。
        TicketThread3 t1 = new TicketThread3(ticket);
        t1.start();

        TicketThread3 t2 = new TicketThread3(ticket);
        t2.start();

        TicketThread3 t3 = new TicketThread3(ticket);
        t3.start();

        TicketThread3 t4 = new TicketThread3(ticket);
        t4.start();

    }
}

//在Thread类中用成员代表火车票或定义静态变量都不合适的情况下,我们可以把火车票单独拿出来,然后传入到线程类中
class Ticket{//代表火车票

    int tickets=100;

}

class TicketThread3 extends  Thread {

    Ticket ticket;

    public TicketThread3(Ticket ticket){
        this.ticket = ticket;
    }

    @Override
    public void run() {
        while (ticket.tickets > 0) {
            synchronized (ticket) {
                if(ticket.tickets>0) {//此片判断是为了避免出现负数的情况
                    System.out.println(Thread.currentThread() + " 已卖   " + ticket.tickets);
                    ticket.tickets--;
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
posted @   shark_zzz  阅读(153)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示