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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 编程的梦想 中级黑马   /  2013-11-7 11:15  /  1213 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

//同步代码块和同步锁
public class ThreadDemo4{
public static void main(String args[]){
  
  tickets t=new tickets();
  Thread t1=new Thread(t);
  Thread t2=new Thread(t);
    t1.start();
  try{Thread.sleep(100);}catch(Exception e){System.out.println("错误");} //主线程休眠后,t1会运行if语句中的代码块,可是为什么主线程唤醒后,执行了  t.flag=false;后,t1还可以执行if语句中的代码块,此时flag不是false吗?不是应该一直在else语句中执行吗???
  t2.start();
  
   }
}
class tickets implements Runnable{
private int tickets=100;
Object obj=new Object();
boolean flag=true;
public void run(){
  if(flag){
   while(true){
    synchronized(obj){
   
     if(tickets>0){
     
      try{Thread.sleep(100);}catch(Exception e){System.out.println("错误");}
      System.out.println(Thread.currentThread().getName()+"----run--"+tickets--);
     }
    }
   }
  }
  else{
   while(true){
    show();
   }
  }
  
}
public synchronized void show(){
  
  if(tickets>0){
     
   try{Thread.sleep(100);}catch(Exception e){System.out.println("错误");}   
   System.out.println(Thread.currentThread().getName()+"---show---"+tickets--);
  }
}

}
我不懂为什么ti线程开启之后不是把flag值重置为false了吗,为什么在ti.start()方法后让主线程休眠一会,那么程序再运行时就是t1和t2的交替运行了呢?此时flag不还是false吗,为什么 System.out.println(Thread.currentThread().getName()+"----run--"+tickets--);这句代码就可以执行,而不是一直执行System.out.println(Thread.currentThread().getName()+"---show---"+tickets--);
主线程难道不是一直存在吗?还是在第一次运行完t1.start();t2.start();之后就消亡了呢???


评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

3 个回复

倒序浏览
主线程睡眠可以让其他线程有运行的机会,你的睡眠时间太短,t1 还没执行完毕,t2就开始执行了,所以你看到的是交替的,这个结果不唯一,有可能主线程睡眠这个时间内,t1就把票卖完了,没有t2;
设置了t.flag=false;但是语句读到while()循环的时候,没出来,这是一个无限循环;第一个进去的线程一直在里面循环,直到票卖完;

评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

回复 使用道具 举报
你出现结果交替运行的现象是因为你同步代码块用的锁和同步函数使用的锁不一样,同步函数中的锁是this,但是你在同步代码块中用的依然是自己定义的对象锁obj,两个锁不统一,各用个的锁,线程不同步,就出现了结果中两个线程交替运行。
修改方式:
同步代码块不能使用obj锁,替换为关键字this,与同步函数的锁一致就OK啦
  1. synchronized(this)
  2.                    {
  3.                              if(tickets>0)
  4.                              {
  5.                              
  6.                               try{Thread.sleep(10);}catch(Exception e){System.out.println("错误");}
  7.                               System.out.println(Thread.currentThread().getName()+"----run--"+tickets--);
  8.                              }
  9.                    }
复制代码
结果如你所期望的,你试试吧。。。

评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

回复 使用道具 举报
你的问题我可以这样回答你吗
第一  你的这个同步只是买票的同步t1在flag=true买票的时候t2不能在flag=true的时候买票但t2可以在flag=false的时候买票,在flag判断中用的不是同一把锁;
第二,即使是同一把锁  在线程操作和打印不是同时的,也就造成了显示的交替性。
第三,就和一楼的意思一样了

评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马