黑马程序员技术交流社区

标题: 多线程卖100张票,一次最多卖3张,这个真被难住了 [打印本页]

作者: 狼色幽默    时间: 2016-10-15 09:31
标题: 多线程卖100张票,一次最多卖3张,这个真被难住了
本帖最后由 狼色幽默 于 2016-10-15 09:36 编辑

RT,卖票的题做过几道了,随机卖,按顺序卖,一次卖几张,这些我都能想出来,唯独这个,一次最多卖3张,我最初的想法是这样的
[Java] 纯文本查看 复制代码
class Ticket extends Thread {
        private static int tickets = 100;
        static Object obj = new Object();
        public Ticket() {
                super();       
        }
        public Ticket(String s) {
                super(s);
        }
        @Override
        public void run() {
                int count = 0;
                while(true) {
                        synchronized (obj) {
                                if(tickets < 0) break;
                                if(count >= 3) break;
                                try{
                                        Thread.sleep(100);
                                        count++;
                                }catch(Exception e) {
                                        e.printStackTrace();
                                }
                                System.out.println(getName() + ":还剩" + tickets-- + "张票");
                        }
                }
        }
}

但结果是每个窗口卖3张票后就停了,每个线程在执行方法时没有相互的影响,执行的时候怎样统计连续出现的次数,并可以用这个次数来暂停线程?
我是真想不出来了,求高手解答

作者: 狼色幽默    时间: 2016-10-15 16:38
本帖最后由 狼色幽默 于 2016-10-15 16:40 编辑

问题我已经想出来了,弄三个线程卖票,每次执行一个,睡眠另外2个,运行完后随机唤醒再运行,每次运行都是随机卖1~3张票,代码比较复杂,但是基本能实现,这里是部分代码
[Java] 纯文本查看 复制代码

class window {
        private static int flag = 1;
        private static int tickets = 100;
        public void win1() throws InterruptedException {
                while(true) {
                        synchronized (this) {
                                if(flag != 1) this.wait();
                                if(tickets > 0){
                                        Random r = new Random();
                                        int count = r.nextInt(3)+1;
                                        for (int i = 0; i < count; i++) {
                                                Thread.sleep(50);
                                                System.out.println("窗口1卖出了1张票,还剩" + tickets-- + "张票");
                                        }
                                }else {
                                        System.out.println("票卖完了");
                                        break;
                                }
                                flag = 2;
                                this.notify();
                        }
                }
        }
        public void win2() throws InterruptedException {
                while(true) {
                        synchronized (this) {
                                if(flag != 2) this.wait();
                                if(tickets > 0){
                                        Random r = new Random();
                                        int count = r.nextInt(3)+1;
                                        for (int i = 0; i < count; i++) {
                                                Thread.sleep(50);
                                                System.out.println("窗口2卖出了1张票,还剩" + tickets-- + "张票");
                                        }
                                }else {
                                        System.out.println("票卖完了");
                                        break;
                                }
                                flag = 3;
                                this.notify();
                        }
                }
        }
        public void win3() throws InterruptedException {
                while(true) {
                        synchronized (this) {
                                if(flag != 3) this.wait();
                                if(tickets > 0){
                                        Random r = new Random();
                                        int count = r.nextInt(3)+1;
                                        for (int i = 0; i < count; i++) {
                                                Thread.sleep(50);
                                                System.out.println("窗口3卖出了1张票,还剩" + tickets-- + "张票");
                                        }
                                }else {
                                        System.out.println("票卖完了");
                                        break;
                                }
                                flag = 1;
                                this.notify();
                        }        
                }
        }
}

作者: 836563696    时间: 2016-10-15 17:24
用个random不就可以了?用不着线程通信吧,又没说按顺序.
作者: 狼色幽默    时间: 2016-10-15 17:37
836563696 发表于 2016-10-15 17:24
用个random不就可以了?用不着线程通信吧,又没说按顺序.

如果直接用random,每次卖票虽然随机卖出1~3张,但是cpu随机分配任务,实际情况可能是1卖出2张,1再卖出3张,这样的结果就是1卖出了5张,可能我自己把题目想复杂了,想了很长时间了,这样虽然复杂但是没有歧义
作者: 836563696    时间: 2016-10-15 17:41
接着拿到执行权多次的话,应该不算一次卖的吧!
作者: 狼色幽默    时间: 2016-10-15 18:21
836563696 发表于 2016-10-15 17:41
接着拿到执行权多次的话,应该不算一次卖的吧!

可以理解成一次执行相当于1个人买票,这个人可以买随机票数,最多一次3张,如果逻辑上不认定一个窗口多次执行为一次卖出多张票,那么直接每次用个random就行了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2