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的之后为什么就顺序输出了?这里有点混淆,求指明人!
延迟1秒执行
我知道是延迟一秒啊,拜托把问题看完啊
你指的乱是什么意思?代码看起来除了
if(list.size()==0) { throw new NoTicketException(); }
这句可能会在某些时刻不生效外没其他问题。
println这个不存在线程抢占,这个方法是需要同步的,这个需要看你用的什么线程池来跑你的runnable了
就是输出,控制台输出不是按照出票 1 2 3 4显示,加了sleep就顺序输出了
你把sleep去掉对比看下控制台输出看看就知道了
@Lawliet__zmz: 这个很正常啊,多线程下又没说要保证顺序性。
@Daniel Cai: 加了sleep就顺序输出了,这段时间线程状态之间是怎么回事啊
@Lawliet__zmz: 你怎么调度你的runnable的?
@Daniel Cai: 不用Runable,直接继承Thread是一样的,重点不在这里啊,关键在sleep这段时间线程发生了什么
@Lawliet__zmz: sleep后线程进入block状态啊。
不管你从哪里继承,这里的关键是你如何运行这些东西的,说个极端的,如果你是fixedThreadPool(1线程)来跑这里就是顺序的,所以你必须要知道你怎么让你的线程跑起来的(或者用的什么样的线程池及queue)
你调度的代码在哪儿?