首页 新闻 会员 周边

Java多线程一个超简单问题,售票模型,大神进来轻松拿分!

0
悬赏园豆:15 [已关闭问题] 关闭于 2017-06-28 18:55
package com.ticket.thread;

import java.util.LinkedList;

import com.sun.org.apache.xalan.internal.xsltc.compiler.sym;

/**
 * 带销售的车票
 * 
 * @author hwyou
 *
 */
public class Ticket {
    
    // 所有的车票(容器)
    LinkedList<Integer> list = new LinkedList<>();
    
    /**
     * 
     * @param size
     *            车票的数量
     */
    public Ticket(int size) {
        for(int i = 1; i <= size; i ++) {
            list.add(i);
        }
        System.out.println(list);
    }
    
    //同步关键字,其他线程在当前线程没有结束之前是不能访问的
    //"试衣间",对当前衣服在试衣间试衣服的时候其他人不能访问
    public  int sell() throws NoTicketException {
//        int t = list.getFirst();
        
        //异常,对正常流程的中断
        if(list.size()==0) {
            throw new NoTicketException();
        }
        
        synchronized(list) {
            int t = list.removeFirst();    
            
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return t;
        }
        
    }
    
    public void show() {
        System.out.println("剩余" + list);
    }

    
}
package com.ticket.thread;

public class SaleTask implements Runnable{
    Ticket ticket;
    
    public SaleTask(Ticket ticket) {
        this.ticket = ticket;
    }
    
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"开放");
        while(true) {
            try {
                int t = ticket.sell();
                System.out.println(Thread.currentThread().getName() + "售出" + t);
            } catch (Exception e) {
                System.out.println(Thread.currentThread().getName() +"售罄");
                break;
            }
        }
    }
    
}

 

不加sleep是输出是乱的,因为在System.out.println打印的时候可能被其他线程抢占,我这里加了sleep的之后为什么就顺序输出了?这里有点混淆,求指明人!

Lawliet__zmz的主页 Lawliet__zmz | 初学一级 | 园豆:4
提问于:2017-06-27 22:11
< >
分享
所有回答(3)
0

延迟1秒执行

知~味~ | 园豆:226 (菜鸟二级) | 2017-06-27 23:55

我知道是延迟一秒啊,拜托把问题看完啊

支持(0) 反对(0) Lawliet__zmz | 园豆:4 (初学一级) | 2017-06-28 08:32
0

你指的乱是什么意思?代码看起来除了

if(list.size()==0) { throw new NoTicketException(); }

这句可能会在某些时刻不生效外没其他问题。

println这个不存在线程抢占,这个方法是需要同步的,这个需要看你用的什么线程池来跑你的runnable了

Daniel Cai | 园豆:10424 (专家六级) | 2017-06-28 10:05

就是输出,控制台输出不是按照出票 1 2 3 4显示,加了sleep就顺序输出了

支持(0) 反对(0) Lawliet__zmz | 园豆:4 (初学一级) | 2017-06-28 10:36

你把sleep去掉对比看下控制台输出看看就知道了

支持(0) 反对(0) Lawliet__zmz | 园豆:4 (初学一级) | 2017-06-28 10:36

@Lawliet__zmz: 这个很正常啊,多线程下又没说要保证顺序性。

支持(0) 反对(0) Daniel Cai | 园豆:10424 (专家六级) | 2017-06-28 10:42

@Daniel Cai: 加了sleep就顺序输出了,这段时间线程状态之间是怎么回事啊

支持(0) 反对(0) Lawliet__zmz | 园豆:4 (初学一级) | 2017-06-28 10:43

@Lawliet__zmz: 你怎么调度你的runnable的?

支持(0) 反对(0) Daniel Cai | 园豆:10424 (专家六级) | 2017-06-28 10:54

@Daniel Cai: 不用Runable,直接继承Thread是一样的,重点不在这里啊,关键在sleep这段时间线程发生了什么

支持(0) 反对(0) Lawliet__zmz | 园豆:4 (初学一级) | 2017-06-28 10:56

@Lawliet__zmz: sleep后线程进入block状态啊。

不管你从哪里继承,这里的关键是你如何运行这些东西的,说个极端的,如果你是fixedThreadPool(1线程)来跑这里就是顺序的,所以你必须要知道你怎么让你的线程跑起来的(或者用的什么样的线程池及queue)

支持(0) 反对(0) Daniel Cai | 园豆:10424 (专家六级) | 2017-06-28 11:02
0

你调度的代码在哪儿?

苍枫露雨 | 园豆:1027 (小虾三级) | 2017-07-04 19:38
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册