黑马程序员--第六篇 多线程之卖票案例

                               第六篇  多线程之卖票案例

 

只有练习,才能内化,下面是运用多线程原理实现的一个卖票程序系统。

要求是:三个窗口同时卖票,不能出现同票,负数票。我们选择Runnable接口的方式

/*

 * 实现Runnable接口的方式实现

 *

 * 通过加入延迟后,就产生了连个问题:

 * A:相同的票卖了多次

 *      CPU的一次操作必须是原子性的

 * B:出现了负数票

 *      随机性和延迟导致的

 */

 

class SellTicket implements Runnable {

 

   // 定义100张票,让三个线程对象共享。

   private static int tickets = 100;

 

   // 定义同一把锁,保证每次只能有一个线程执行同步代码块。

   private Object obj = new Object();   //不过此处的对象可以是任意的。

       

   //同步代码块用obj做锁

   @Override

   public void run() {

      while (true) {

        synchronized (obj) {

           if (tickets > 0) {

      //此处需要处理异常,但是其父类都没有抛出异常,子类就只能Try..catch来处理。

try {

                 //为了模拟现实中售票会存在网络延迟。所以加入了睡眠100ms.

Thread.sleep(100);

              } catch (InterruptedException e) {

                 e.printStackTrace();

              }

              System.out.println(Thread.currentThread().getName()

                    + "正在出售第" + (tickets--) + "张票 ");

           }

        }

      }

   }

//      }

//    }

 

public class SellTicketDemo {

   public static void main(String[] args) {

      // 创建资源对象

      SellTicket st = new SellTicket();

 

      // 创建三个线程对象

      Thread t1 = new Thread(st, "窗口1");

      Thread t2 = new Thread(st, "窗口2");

      Thread t3 = new Thread(st, "窗口3");

 

      // 启动线程

      t1.start();

      t2.start();

      t3.start();

   }

}

    总结:1电影院卖票程序可能出现的问题及解决。

                 卖票问题

                  a:同票多次

                  b:会出现负数票

      2,多线程安全问题的原因(也是我们以后判断一个程序是否有线程安全问题的依据)

           A:是否有多线程环境

           B:是否有共享数据

           C:是否有多条语句操作共享数据

      3,同步解决线程安全问题

           A:同步代码块

                 synchronized(对象) {

                      需要被同步的代码;

                 }

                

                 这里的锁对象可以是任意对象。

           注意:锁对象要能被所有线程对象共享,这样确保每次只有一个线程对象执行同步代码块。

                

           B:同步方法

                 把同步加在方法上。

                

                 这里的锁对象是this

                

           C:静态同步方法

                 把同步加在方法上。

                

                 这里的锁对象是当前类的字节码文件对象(反射再讲字节码文件对象)

posted on 2015-11-16 20:22  大势  阅读(42)  评论(0)    收藏  举报