Java~多线程算法实战题目之商店售票

文章目录


PS:这道题是我在面试中遇到的,所以没有链接, 感觉这道题很有意思就拿出来分享分享

题目描述

有一个商店有100张票,并且有三个售票口, 这三个售票口之间独立, 各卖各的, 但是票不是独立的, 每张票不能重复卖。

注意:
100张票必须全部卖出, 但是不能多卖。
每个窗口每隔100毫秒卖出一张票。

要求:
输出每张票是被哪个窗口卖出

思路

这是一个很典型的多线程安全问题, 因为票一旦操作不当就会被重复卖出

所以这道题的关键点就在于每个售票口在查看此时票还剩多少和取票这俩个操作必须保证同步

那我们就使用一个同步方法来保证上述俩个操作的同步进行。

class Store {
    
    

    private volatile int ticket = 1;

    /**
     * A售票口
     * @throws InterruptedException
     */
    public void A() throws InterruptedException {
    
    

        int temp;
        while ((temp = getSetTicket()) != -1) {
    
    
            System.out.println(temp + " A");
            Thread.sleep(100);
        }
    }

    /**
     * B售票口
     * @throws InterruptedException
     */
    public void B() throws InterruptedException {
    
    
        
        int temp;
        while ((temp = getSetTicket()) != -1) {
    
    
            System.out.println(temp + " B");
            Thread.sleep(100);
        }
    }

    /**
     * 售票口
     * @throws InterruptedException
     */
    public void C() throws InterruptedException {
    
    
        
        int temp;
        while ((temp = getSetTicket()) != -1) {
    
    
            System.out.println(temp + " C");
            Thread.sleep(100);
        }
    }

    /**
     * 查看票和取票的同步操作
     * @return
     */
    public synchronized int getSetTicket() {
    
    
        int temp = this.ticket;

        //查看此时票是否能卖出
        if (temp > 100) {
    
    
            return -1;
        }
        
        //取票
        this.ticket++;
        return temp;
    }
}

测试

启用三个线程去同时调用三个窗口

    public static void main(String[] args) throws InterruptedException {
    
    
        Store store = new Store();
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    store.A();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        }).start();

        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    store.B();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        }).start();

        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    store.C();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        }).start();

        Thread.sleep(1000);
    }

测试结果

1 A
2 B
3 C
4 A
6 C
5 B
7 A
8 C
9 B
10 A
11 C
12 B
13 A
14 C
15 B
16 A
17 C
18 B
19 A
20 C
21 B
22 A
23 C
24 B
25 A
26 C
27 B
28 A
29 C
30 B
31 A
33 B
32 C
34 A
35 C
36 B
37 A
38 C
39 B
40 A
41 B
42 C
43 A
45 C
44 B
46 A
48 B
47 C
49 A
50 C
51 B
52 A
53 C
54 B
55 A
56 B
57 C
58 A
59 B
60 C
61 A
62 B
63 C
64 A
66 B
65 C
67 A
68 B
69 C
70 A
72 C
71 B
73 A
74 C
75 B
76 A
77 C
78 B
79 A
80 C
81 B
82 A
83 C
84 B
85 A
87 B
86 C
88 A
89 B
90 C
91 A
92 B
93 C
94 A
95 B
96 C
97 A
98 B
99 C
100 A

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/Shangxingya/article/details/114366295
今日推荐