A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 胡高德 中级黑马   /  2012-12-6 22:28  /  1806 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

/*
模拟售票系统  有100张票,四个人去买这些票
显示出每个人都买到了第几号票
分析:因为这四个人谁能买到第几张票是随机的所有使用多线程来操作

当前程序出现的问题?
我们相当于两个窗口同时去售票,
那么我们使用的这四个线程对象可以
在两个窗口中任意的一个去买票。
票只有100张,我们在两个售票窗口的方法中,
都使用了同步.
问题是 sellTicket1所使用是同步方法,那么同步方法使用的锁是什么?
sellTicket2所使用的是同步代码块,它所使用的锁是obj
多线程程序中要想保证当前线程是同步的,必须保证使用同一个锁。
同步方法其实也使用的锁,他的锁对象是this。
那么如果你在多线程程序中同步方法与同步代码块共同出现,为了保证
使用同一把锁,这个时候同步代码块所使用的对象也要是this
*/
class Test5
{
public static void main(String[] args)
{
  
  TicketWindow tw=new TicketWindow();
  Thread th1=new Thread(tw);
  Thread th2=new Thread(tw);
  Thread th3=new Thread(tw);
  Thread th4=new Thread(tw);
  th1.setName("张三");
  th2.setName("李四");
  th3.setName("王五");
  th4.setName("赵六");
  th1.start();
  th2.start();
  th3.start();
  th4.start();
}
}

/*
售票窗口
*/
class TicketWindow implements Runnable
{
static int ticket=100; //代表100张票

//Object obj=new Object();
static boolean flag=true;//开关,可以让四个线程都去执行这两个售票窗口.
//售票方法
public  static synchronized void sellTicket1(){  
  //当前的同步方法所使用的锁对象是哪个对象?  默认使用的锁就是this
  //如果是static方法,所使用的锁是 类名.class 对象
   flag=false;
  
   if(ticket>0){
   
    System.out.println(Thread.currentThread().getName()+" 买到了第"+ticket+"张票");
    ticket--;
   }
  
}
//售票方法
public  void sellTicket2(){
  
  flag=true;
  synchronized(TicketWindow.class){
   if(ticket>0){
   
    System.out.println(Thread.currentThread().getName()+" 买到了第"+ticket+"张票");
    ticket--;
   }
  }
}

public void run(){
  
  while(true){
   
   if(flag){
    sellTicket1();
   }else{
    sellTicket2();
   }
  }
}
}
/*
解决安全问题  
1. 同步代码块
2. 同步方法
同步方法,如果方法是实例方法,那么它默认所使用的锁是 this
如果同步方法是静态的方法,那么它默认所使用的锁的 类名.class 对象.
*/

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

1 个回复

正序浏览
复习一下。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马