随笔 - 88  文章 - 0 评论 - 10 阅读 - 10万
< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package ccb.ticket;
 
import java.io.File;
import java.util.ArrayList;
/*
功能实现:多线程模拟售票系统
定义一个车票类,车票类拥有票号属性、  车票状态(未售、售出)属性和拥有者(String类型)属性;
    在主线程中定义一个票库(ArrayList数组列表)初始化票库并生产200张票;
定义一个乘客类继承自线程类,有一个名字(String类型)属性, 乘客类每隔10毫秒就去票库中查看有没票,
    如果有票就抢一张过来 (把车票标为售出状态,并把车票的拥有者标为自己的名字), 每个乘客抢到20张票就停止运行。
在主线程中创建10个乘客类并启动它们(开始抢票), 要求每个乘客抢到的票不连号,不能多抢或少抢。抢完后打印出每个人抢到的票号。
*/
public class Main {
    //票库
    static ArrayList<Ticket> mTicketList = new ArrayList<Ticket>();
 
    public static void main(String[] args) {
        for (int i = 0; i < 200; i++) {
            Ticket t = new Ticket();
            t.ticketNum = i + 100;
            mTicketList.add(t);
        }
        Passenger[] passengers = new Passenger[5];
        for (int i = 0; i < 5; i++) {
            passengers[i] = new Passenger("passenger_" + i/*,mTicketList*/);
            passengers[i].start();
        }
 
        //等待所有乘客结束
        for (int i = 0; i < 5; i++) {
            try {
                passengers[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
 
        for (int i = 0; i < passengers.length; i++) {
            System.out.print(passengers[i].name + "抢到的票:");
            int tCnt = 0; //抢到的票数
            for (int j = 0; j < mTicketList.size(); j++) {
                Ticket t = mTicketList.get(j);
 
                if (t != null && t.owner != null && passengers[i] != null) {
                    if (t.owner.equals(passengers[i].name)) {
                        tCnt++;
                        System.out.print(t.ticketNum + ",");
                    }
                }
            }
            System.out.println("总票数:" + tCnt);
        }
    }
 
}

购票人:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package ccb.ticket;
 
/**
 * 旅客线程(并发)
 */
 
public class Passenger extends Thread {
    String name;//名字
    //ArrayList<Ticket> mTicketList ;
    int myTickets = 0;
 
    public Passenger(String name/*,ArrayList<Ticket> ticketList*/) {
        //mTicketList = ticketList;
        this.name = name;
    }
 
    @Override
    public void run() {
        //Main.mTicketList.get(0);
        while (myTickets < 20) {
            //开始抢票
            for (int i = 0; i < Main.mTicketList.size(); i++) {
                Ticket t = Main.mTicketList.get(i); //取出第i张票
                synchronized (t) { //synchronized (监视的竞争对象)
                    if (t.saledState == Ticket.STATE_NOT_SALED) {
                        //把车票标为售出状态
                        t.saledState = Ticket.STATE_SALED;
                        //把车票的拥有者标为自己的名字
                        t.owner = this.name;
                        myTickets++;
                        System.out.println(Thread.currentThread().getName() + this.name + " 抢到" + t.ticketNum + "号票");
                        break;
                    }
                }
                /*
                boolean result = checkTicket(t);
                if(result){
                    break;
                }*/
            }
 
            try {
                sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
 
    /*
     * synchronized 默认监视的竞争对象 : 为当前类对象,即this
     */
    public synchronized boolean checkTicket(Ticket t) {
        if (t.saledState == Ticket.STATE_NOT_SALED) {
            t.saledState = Ticket.STATE_SALED; //把车票标为售出状态
            t.owner = this.name; //把车票的拥有者标为自己的名字
            myTickets++;
            System.out.println(this.name + "抢到" + t.ticketNum + "号票");
            return true;
        }
        return false;
    }
}

  车票:

1
2
3
4
5
6
7
8
9
10
package ccb.ticket;
 
public class Ticket {
    public static final boolean STATE_SALED = true;         //售出状态
    public static final boolean STATE_NOT_SALED = false;    //未售出状态
 
    public int ticketNum = 0;                           //票号
    public boolean saledState = STATE_NOT_SALED;        //初始状态: 未售
    public String owner = null;                         //拥有者
}

  

  一个很好的示例,受到了很大的启发!原文出处记不起来了,侵删!

 

posted on   jarod99  阅读(303)  评论(0编辑  收藏  举报
编辑推荐:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
阅读排行:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
点击右上角即可分享
微信分享提示