当前位置: 代码迷 >> Java相关 >> 关于线程同步:卖票问题!! 为什么票数溢出!
  详细解决方案

关于线程同步:卖票问题!! 为什么票数溢出!

热度:320   发布时间:2011-04-15 15:28:52.0
关于线程同步:卖票问题!! 为什么票数溢出!
//问题:
//假设有火车票100张,创建10个线程模拟10个售票点,每个售票点500毫秒买一张票。打印出售票过程,注意使用synchronized确保同一张票只能卖出一次。

class TicketsSell implements Runnable {
         
   
         static int tickets=1;//实例化票数
    int num;

    public TicketsSell(int num) {//  构造方法
        this.num = num;
    }

    public  synchronized void run() {
      //synchronized(this){// 同步该方法
        for (int i=0; i< 100; i++) {
               

           if(tickets<100) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("第" + num + "售票点卖出第" + (tickets++) + "张票");
   
            }
            
           }
           
      
    }
}

public class Station {

    public static void main(String[] args) {
        
       Thread wicket1 = new Thread(new TicketsSell(1));
        Thread wicket2 = new Thread(new TicketsSell(2));
        Thread wicket3 = new Thread(new TicketsSell(3));
        Thread wicket4 = new Thread(new TicketsSell(4));
        Thread wicket5 = new Thread(new TicketsSell(5));
        Thread wicket6 = new Thread(new TicketsSell(6));
        Thread wicket7 = new Thread(new TicketsSell(7));
        Thread wicket8 = new Thread(new TicketsSell(8));
        Thread wicket9 = new Thread(new TicketsSell(9));
        Thread wicket10 = new Thread(new TicketsSell(10));
        wicket1.start();
        wicket2.start();
        wicket3.start();
        wicket4.start();
        wicket5.start();
        wicket6.start();
        wicket7.start();
        wicket8.start();
        wicket9.start();
        wicket10.start();
      
    }

}
运行结果: 为什么会超出100张! 我找不出错误,知道的说下!

搜索更多相关的解决方案: 火车票  售票点  

----------------解决方案--------------------------------------------------------
提示: 作者被禁止或删除 内容自动屏蔽
2011-04-15 08:31:16
llooppzhang

来 自:江苏
等 级:黑侠
威 望:5
帖 子:308
专家分:518
注 册:2009-10-18
  得分:4 
      System.out.println("第" + num + "售票点卖出第" + (tickets++) + "张票");
                  try {
                     Thread.sleep(500);   
                  } catch (InterruptedException e) {e.printStackTrace();}
这样写没有溢出,eclipse编辑器下,5遍。。

----------------解决方案--------------------------------------------------------
回复 2楼 付政委
第1售票点卖出第1张票
第2售票点卖出第1张票
第3售票点卖出第1张票
第5售票点卖出第1张票
第7售票点卖出第1张票
第6售票点卖出第1张票
第4售票点卖出第1张票
第8售票点卖出第1张票
第9售票点卖出第1张票
第10售票点卖出第1张票
这里有点不对劲。。。。

----------------解决方案--------------------------------------------------------
是会溢出。。我觉得在调用每个线程的时候用个join()方法就可以。。有点笨,呵呵。
----------------解决方案--------------------------------------------------------
回复 4楼 llooppzhang
public  synchronized void run()

这样锁住的是对象,不是类,没有达到同步的作用。

你可以用同步块这样写:
程序代码:

synchronized (TicketsSell.class) {
    // 这里写对TicketsSell.tickets的操作
}


[ 本帖最后由 buffer 于 2011-4-15 22:42 编辑 ]
----------------解决方案--------------------------------------------------------
回复 6楼 buffer
那是锁定方法,在think in java 里也有这样用的,但好像没有在Thread.run()上用synchronized的,我在run()方法里用了synchronized,和你的一样。。。

----------------解决方案--------------------------------------------------------
回复 7楼 llooppzhang
public synchronized void run()和synchronized(this){...}的作用是一样的,锁住的都是对象,也就是说
虽然同一个对象不能在不同线程内同时调用这个方法。但是不同的对象却可以同时访问该方法。
所以这样那十个线程并没有获得同步控制。
而synchronized(TicketsSell.class){...}锁住的是TicketsSell这个类。这样就可以同步TicketsSell的静态成员tickets。
程序代码:
// Sync.java
public class Sync {
    public static void main(String[] args) {
        Thread[] threads = new Thread[10];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new Ticket(i + 1));
            threads[i].start();
        }
    }
}

class Ticket implements Runnable {
    private static final int TOTAL_TICKETS = 100;
    static int countTicket = 1;
    int number;

    public Ticket(int num) {
        number = num;
    }

    @Override
    public void run() {
        for (int i = 1; i <= TOTAL_TICKETS; i++) {
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
            synchronized (Ticket.class) {
                if (Ticket.countTicket <= TOTAL_TICKETS) {
                    System.out.println("第" + number + "售票点卖出第"
                            + (Ticket.countTicket++) + "张票");
                }
            }
        }
    }
}
本帖最近评分记录
2011-04-16 04:28:42
buffer

等 级:职业侠客
帖 子:73
专家分:326
注 册:2010-12-31
  得分:0 
程序运行输出:
第1售票点卖出第1张票
第3售票点卖出第2张票
第4售票点卖出第3张票
第2售票点卖出第4张票
第5售票点卖出第5张票
第6售票点卖出第6张票
第7售票点卖出第7张票
第10售票点卖出第8张票
第9售票点卖出第9张票
第8售票点卖出第10张票
第1售票点卖出第11张票
第4售票点卖出第12张票
第2售票点卖出第13张票
第3售票点卖出第14张票
第5售票点卖出第15张票
第7售票点卖出第16张票
第6售票点卖出第17张票
第8售票点卖出第18张票
第9售票点卖出第19张票
第10售票点卖出第20张票
第1售票点卖出第21张票
第2售票点卖出第22张票
第4售票点卖出第23张票
第3售票点卖出第24张票
第5售票点卖出第25张票
第6售票点卖出第26张票
第7售票点卖出第27张票
第8售票点卖出第28张票
第10售票点卖出第29张票
第9售票点卖出第30张票
第1售票点卖出第31张票
第4售票点卖出第32张票
第2售票点卖出第33张票
第3售票点卖出第34张票
第6售票点卖出第35张票
第5售票点卖出第36张票
第7售票点卖出第37张票
第10售票点卖出第38张票
第8售票点卖出第39张票
第9售票点卖出第40张票
第1售票点卖出第41张票
第2售票点卖出第42张票
第3售票点卖出第43张票
第4售票点卖出第44张票
第6售票点卖出第45张票
第7售票点卖出第46张票
第5售票点卖出第47张票
第10售票点卖出第48张票
第8售票点卖出第49张票
第9售票点卖出第50张票
第1售票点卖出第51张票
第2售票点卖出第52张票
第4售票点卖出第53张票
第3售票点卖出第54张票
第5售票点卖出第55张票
第7售票点卖出第56张票
第8售票点卖出第57张票
第6售票点卖出第58张票
第10售票点卖出第59张票
第9售票点卖出第60张票
第1售票点卖出第61张票
第2售票点卖出第62张票
第4售票点卖出第63张票
第5售票点卖出第64张票
第9售票点卖出第65张票
第8售票点卖出第66张票
第10售票点卖出第67张票
第6售票点卖出第68张票
第7售票点卖出第69张票
第3售票点卖出第70张票
第1售票点卖出第71张票
第4售票点卖出第72张票
第2售票点卖出第73张票
第5售票点卖出第74张票
第9售票点卖出第75张票
第6售票点卖出第76张票
第10售票点卖出第77张票
第8售票点卖出第78张票
第7售票点卖出第79张票
第3售票点卖出第80张票
第1售票点卖出第81张票
第4售票点卖出第82张票
第2售票点卖出第83张票
第5售票点卖出第84张票
第9售票点卖出第85张票
第3售票点卖出第86张票
第7售票点卖出第87张票
第10售票点卖出第88张票
第6售票点卖出第89张票
第8售票点卖出第90张票
第1售票点卖出第91张票
第2售票点卖出第92张票
第4售票点卖出第93张票
第5售票点卖出第94张票
第9售票点卖出第95张票
第3售票点卖出第96张票
第7售票点卖出第97张票
第10售票点卖出第98张票
第6售票点卖出第99张票
第8售票点卖出第100张票

----------------解决方案--------------------------------------------------------
程序代码:
Thread[] threads = new Thread[10];
这句怎么理解?
----------------解决方案--------------------------------------------------------
  相关解决方案