黑马程序员技术交流社区

标题: 卖票问题 [打印本页]

作者: 小白马__^o^    时间: 2014-7-31 15:19
标题: 卖票问题
大神们!我想用同步方法,还有就是多个服务器,多个线程,把100张票卖掉,每个线程剩余的票数不能有重复,这该怎么做啊!以下是我的错误代码,还望大神帮我改一下:


  1. class Duo implements Runnable
  2. {
  3.         int piao = 100;
  4.         //public static Object obj = new Object();

  5.         public void run()
  6.         {
  7.                 while(true)
  8.                 {
  9.                         sale();
  10.                 }
  11.                        
  12.         }

  13.         public synchronized void sale()
  14.         {
  15.                
  16.                 if(piao > 0)
  17.                 {
  18.                         System.out.println(Thread.currentThread().getName() + ":" + piao);
  19.                         piao--;

  20.                         notifyAll();
  21.                         try
  22.                         {
  23.                                 wait();
  24.                         }
  25.                         catch (Exception e)
  26.                         {
  27.                         }
  28.                        
  29.                 }
  30.         }
  31. }

  32. class Suo
  33. {
  34.         public static void jiaSuo()
  35.         {
  36.                 System.out.println("我加锁了<--->");
  37.         }
  38. }

  39. public class DuoXian
  40. {
  41.         public static void main(String args[])
  42.         {
  43.                 Duo duo = new Duo();
  44.                 Duo duo1 = new Duo();
  45.                 Duo duo2 = new Duo();

  46.                 Thread s = new Thread(duo);
  47.                 Thread s2 = new Thread(duo1);
  48.                 Thread s3 = new Thread(duo2);

  49.                 s.start();
  50.                 s2.start();
  51.                 s3.start();

  52.                 //System.out.println(Thread.currentThread().getName());
  53.         }
  54. }
复制代码

这是错误的效果:




作者: 裤裆里的温柔、    时间: 2014-7-31 16:37
class Suo
{
        public static void jiaSuo()
        {
                System.out.println("我加锁了<--->");
        }
}
这个干么用的
作者: masai158    时间: 2014-7-31 16:53
public class Test014
{
        static int count = 1000000;
       
        public static void main(String[] args)
        {
                long startTime = System.currentTimeMillis();
                Object obj = new Object();
                Thread ck1 = new Thread(new Window1(obj),"窗口11111");
                Thread ck2 = new Thread(new Window2(obj),"窗口222");
                Thread ck3 = new Thread(new Window3(obj),"窗口33333333333");
                ck1.start();
                ck2.start();
                ck3.start();
                try
                {
                        ck1.join();
                        ck2.join();
                        ck3.join();
                } catch (InterruptedException e) {
                       
                        e.printStackTrace();
                }
               
                long endTime = System.currentTimeMillis();
                System.out.println("3个窗口卖 1000000 张票共耗时:" + (endTime - startTime)/1000 + "秒");
               
        }

}

class Window1 implements Runnable
{
        int window1Count=0;
        private Object obj;
        Window1(Object obj)
        {
                this.obj = obj;
        }
        public void run()
        {
                while(Test014.count > 0)
                {
                        synchronized(obj)
                        {
                                if(Test014.count > 0)
                                {
                                        window1Count++;
                                        Test014.count --;
                                        System.out.println(Thread.currentThread().getName() +
                                                "卖出一张票,现在还剩:" + Test014.count + "共计卖出:" + window1Count);
                                }
                        }
                }       
        }
}
class Window2 implements Runnable
{
        int window2Count=0;
        private Object obj;
        Window2(Object obj)
        {
                this.obj = obj;
        }

        public void run()
        {
                while(Test014.count > 0)
                {
                        synchronized(obj)
                        {
                                if(Test014.count > 0)
                                {
                                        window2Count++;
                                        Test014.count --;
                                        System.out.println(Thread.currentThread().getName() +
                                                "卖出一张票,现在还剩:" + Test014.count + "共计卖出:" + window2Count);
                                }
                        }
               
                }
        }
}
class Window3 implements Runnable
{
        int window3Count=0;
        private Object obj;
        Window3(Object obj)
        {
                this.obj = obj;
        }
       
        public void run()
        {
                while(Test014.count > 0)
                {
                        synchronized(obj)
                        {
                                if(Test014.count > 0)
                                {       
                                        window3Count++;
                                        Test014.count --;
                                        System.out.println(Thread.currentThread().getName() +
                                        "卖出一张票,现在还剩:" + Test014.count + "共计卖出:" + window3Count);
                                }
                        }
                       
                }
        }
}
作者: 肖岩    时间: 2014-7-31 19:12
你写wait放在notifyAll,线程就挂起了,当然卖不下去了.而且你创建了3个Duo对象,是要卖300张票?
作者: 小白马__^o^    时间: 2014-7-31 20:57
masai158 发表于 2014-7-31 16:53
public class Test014
{
        static int count = 1000000;

嗯...,大神!能不能做到窗口1卖一张,窗口2卖一张,窗口3卖一张,然后再窗口1卖一张..............,这样可不可以啊!还请大神指教指教!{:2_32:}
作者: fxwb2005    时间: 2014-7-31 21:13
  1. package com.chapter3;

  2. class Xc2 implements Runnable
  3. {
  4.        
  5.         public static int cp=100;
  6.         static String aa= new String("1");
  7.        
  8.         public void run()
  9.         {
  10.                 while(true)
  11.                 {
  12.                         synchronized (aa)
  13.                         {
  14.                             if(cp>0)
  15.                             {
  16.                                     System.out.println("第"+Thread.currentThread().getName()+"个车站正在卖第"+(101-cp)+"张车票");
  17.                         --cp;                       
  18.                             }else
  19.                             {
  20.                                      break;
  21.                                
  22.                             }
  23.                         }
  24.                 }
  25.                
  26.         }

  27. }

  28. public class Xc
  29. {
  30.         public static void main(String[] args)
  31.         {
  32.                 Xc2 xc2_1 = new Xc2();
  33.                 Thread ee= new Thread(xc2_1);
  34.                 ee.start();
  35.                
  36.                 Xc2 xc2_2 = new Xc2();
  37.                 Thread ff= new Thread(xc2_2);
  38.                 ff.start();
  39.         }

  40. }
复制代码
这是之前看教程的时候照着敲过的,不会重复卖票,不过100张票有时候看不出效果,至于每个线程走一次,用:this.wait();让当前线程进入等待状态
this.notify();叫醒另外一个线程
这两个方法不知道可不可以实现,没有试过……  


作者: hdchenyue    时间: 2014-7-31 21:29
楼上正解。。。
作者: 0小菜鸟0    时间: 2014-7-31 21:52
确实,学到不少
作者: masai158    时间: 2014-7-31 23:47
本帖最后由 masai158 于 2014-7-31 23:54 编辑
小白马__^o^ 发表于 2014-7-31 20:57
嗯...,大神!能不能做到窗口1卖一张,窗口2卖一张,窗口3卖一张,然后再窗口1卖一张..............,这 ...

卖一张就睡觉。等待其他线程唤醒。
1卖了,睡觉。。只 唤醒2.
2卖了,睡觉。。。只 唤醒3
3卖了,睡觉。。只唤醒1
作者: 大★宝    时间: 2014-8-7 11:31
知识回顾,赞
作者: laibin2    时间: 2014-8-7 11:42
                Duo duo = new Duo();
                Duo duo1 = new Duo();
                Duo duo2 = new Duo();

                Thread s = new Thread(duo);
                Thread s2 = new Thread(duo1);
                Thread s3 = new Thread(duo2);
创建了三个资源,三个线程都在执行不同的资源,所以
                        notifyAll();
                        try {
                                wait();
                        } catch (Exception e) {
                        }
都不能唤醒其他两个线程,所以都是卖了一张票就wait()了.
解决方法,只能new 一个DUo,让三个线程执行一个资源.
重点                Duo duo = new Duo();
                Thread s = new Thread(duo);
                Thread s2 = new Thread(duo);
                Thread s3 = new Thread(duo);




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