//21.用JAVA中的多线程示例火车站售票问题
//火车站售票,票有个成员记录自己的票数,
class Ticket{
   private int num;
   private static Ticket instance= null;

   public static Ticket getInstance( int num){
     if(instance == null){
      instance = new Ticket(num);
    }
     return instance;
  }
   private Ticket( int num){
     this.num = num;
  }

   public int getNum() {
     return num;
  }

   public void setNum( int num) {
     this.num = num;
  }
   public synchronized void sale(){
     if( this.num > 0){
      System.out.println(Thread.currentThread().getName()+ "卖出了一张票");
       this.num--;
      System.out.println( "还有: "+num+ " 张票!");
    }
  }
}
class SaleTicket implements Runnable{
   private Ticket ticket;
   public SaleTicket( int num){
     this.ticket = Ticket.getInstance(num);
  }
   public void run() {
     while(ticket.getNum() > 0){
      ticket.sale();
       try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}
public class TestSaleTicket {
   public static void main(String[] args) {
    SaleTicket ticket = new SaleTicket(20);
     new Thread(ticket, "甲--->").start();
     new Thread(ticket, "乙--->").start();
     new Thread(ticket, "丙--->").start();
  }
}
    火车站售票的程序感觉和上个银行取款的程序完全一样,但是这么写未免太麻烦了,把票单独抽象出一个类,有票数的成员变量还有卖票的成员方法,要启动多个线程卖票,必须用单例模式,共享票的记录。。所以有点复杂
    联想到实现Runnable接口的线程可以实现共享数据,形成线程池。所以可以把票类里的成员变量和方法 放到Runnable接口的子类中,方便管理。
//21.用JAVA中的多线程示例火车站售票问题
//火车站售票,票有个成员记录自己的票数,
class SaleTicket implements Runnable{
   private int num;
   public SaleTicket( int num){
     this.num = num;
  }
   public void run() {
     while( this.num > 0){
      sale();
       try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
   public synchronized void sale(){
     if( this.num > 0){
      System.out.println(Thread.currentThread().getName()+ "卖出了一张票");
       this.num--;
      System.out.println( "还有: "+num+ " 张票!");
    }
  }
}
public class TestSaleTicket {
   public static void main(String[] args) {
    SaleTicket ticket = new SaleTicket(20);
     new Thread(ticket, "甲--->").start();
     new Thread(ticket, "乙--->").start();
     new Thread(ticket, "丙--->").start();
  }
}
实现了多线程操作,前面银行的例子中多线程是靠继承Thead的例子实现的,所以只能抽象出一个单独的类,以实现对象的共享,如果将其改造,实现Runnable接口,和卖票程序应该是完全一样的。。。。

另外同步分为同步代码块和同步代码方法,同步代码块容易放错位置,所以我就用同步代码方法,简单易用