需求:编写三各类Ticket、SealWindow、TicketSealCenter分别代表票信息、售票窗口、售票中心。售票中心分配一定数量的票,由若干个售票窗口进行出售。 运行的时候有重复的票号,我已经在卖票的方法上添加了synchronized关键字,还是会出现问题,但是我找不到问题出在哪里了,谢谢大家了 public class TicketDemo { public static void main(String[] args) { new Thread(new SealWindow("1号窗口")).start(); new Thread(new SealWindow("2号窗口")).start(); new Thread(new SealWindow("3号窗口")).start(); new Thread(new SealWindow("4号窗口")).start(); } } //票信息 class Ticket { private static int ticketid; public static int getTicketid() { return ticketid; } public static void setTicketid(int ticket) { ticketid = ticket; } } //售票窗口 class SealWindow implements Runnable { private String ticketname; TicketSealCenter tsc = null;; public SealWindow(String ticketname){ this.ticketname = ticketname; tsc = TicketSealCenter.getInstance(); } public void sellTicket(){ while(!tsc.hasTicket()){ System.out.println(ticketname+"卖出了第" + tsc.getid()+"号票!"); if (tsc.hasTicket()) { System.out.println(ticketname+"的票已卖完!"); } } } public void run() { sellTicket(); } } //售票中心 class TicketSealCenter { private static TicketSealCenter tsc = new TicketSealCenter(); private static Ticket ticket = new Ticket(); private static int sumticket = 100; private static boolean flag = false; private TicketSealCenter(){} public static TicketSealCenter getInstance(){ return tsc; } //询问是否有票,设置票面ID,并返回该ID public static synchronized boolean hasTicket(){ if(sumticket > 0){ ticket.setTicketid(sumticket); sumticket--; }else { flag =true; } return flag; } public int getid(){ return ticket.getTicketid(); } } |
|
因为你的synchronized是加在对象上的,但是你在建线程的时候,又新建了好几个匿名对象,这就意味着每个对象都有它自己的synchronized,所以这几个线程也就不互斥,因为它们不共享synchronized。正确的做法是只需要建一个对象,然后让这几个线程共享一个对象。像“1号窗口”、“2号窗口”可以设置为线程的名字,而不是对象的属性。
|
|
15分 |
public class TicketDemo { public static void main(String[] args) { SealWindow myWindow=new SealWindow(); new Thread(myWindow,"1号窗口").start(); new Thread(myWindow,"2号窗口").start(); new Thread(myWindow,"3号窗口").start(); new Thread(myWindow,"4号窗口").start(); } } //票信息 class Ticket { private static int ticketid; public static int getTicketid() { return ticketid; } public static void setTicketid(int ticket) { ticketid = ticket; } } //售票窗口 class SealWindow implements Runnable { TicketSealCenter tsc = null; public SealWindow(){ tsc = TicketSealCenter.getInstance(); } public void sellTicket(){ while(!tsc.hasTicket()){ // System.out.println(Thread.currentThread().getName()+"卖出了第" + tsc.getid()+"号票!"); if (tsc.hasTicket()) { System.out.println(Thread.currentThread().getName()+"的票已卖完!"); } } } public void run() { sellTicket(); } } //售票中心 class TicketSealCenter { private static TicketSealCenter tsc = new TicketSealCenter(); private static Ticket ticket = new Ticket(); private static int sumticket = 100; private static boolean flag = false; private TicketSealCenter(){} public static TicketSealCenter getInstance(){ return tsc; } //询问是否有票,设置票面ID,并返回该ID public static synchronized boolean hasTicket(){ if(sumticket > 0){ ticket.setTicketid(sumticket); System.out.println(Thread.currentThread().getName()+"卖出了第" + tsc.getid()+"号票!"); sumticket--; }else { flag =true; } return flag; } public int getid(){ return ticket.getTicketid(); } } |
5分 |
您说的不对吧,不是因为创建了多个对象,而是因为 |
5分 |
恩 主要楼主用的是单例设计模式,不管创建多少个SealWindow,共享的都是一个TicketSealCenter对象。你的意思我在上述代码中已经有所体现了。
|
5分 |
很简单的代码,撸主给弄好凌乱,很简单的锁机制,撸主却乱加。
减票方法你是加锁了,可是获取票的方法你考虑过么? 如果一个线程都执行了public static synchronized boolean hasTicket()这个方法后,执行权交给另一个线程,另一个线程也跑了这个方法,后面类推,接着多个线程开始执行public int getid()方法,你觉得票是多了呢,还是少了呢? |
多谢了 我刚开始学java 思路有些混乱 之后自己又缕清了思路 重新写了下 现在不会出现安全问题了 还是十分的感谢你 |