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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ぺsimon☆ 中级黑马   /  2013-5-15 17:07  /  1148 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 ぺsimon☆ 于 2013-5-16 00:06 编辑
  1. /*
  2. 有100张票,4个窗口在同时卖票,用多线程实现
  3. */


  4. class Ticket implements Runnable
  5. {
  6.         //定义100张票
  7.         private static int ticket=100;
  8.         boolean flag=true;
  9.         
  10.         //覆盖run方法
  11.         public void run()
  12.         {

  13.         synchronized(this)
  14.         {


  15.         while(flag==true && ticket>0)
  16.         {
  17.         try{Thread.sleep(10);}catch(Exception e){e.toString();}
  18.         System.out.println(Thread.currentThread().getName()+"....."+ticket--);

  19.         }
  20.         
  21.         }

  22. //调用show方法
  23.         show();
  24.         }

  25.         public synchronized void show()
  26.         {

  27.         while(flag==false && ticket>0)
  28.         {
  29.         try{Thread.sleep(10);}catch(Exception e){e.toString();}
  30.         System.out.println(Thread.currentThread().getName()+"------"+ticket--);

  31.         }
  32.         }
  33.         
  34.         
  35.         
  36. }

  37. class TicketDemo
  38. {
  39.         public static void main(String[] args)
  40.         {
  41.         Ticket t=new Ticket();

  42.         Thread t1=new Thread(t);
  43.         t1.start();
  44. //让主线程睡一会
  45.         try{Thread.sleep(10);}catch(Exception e){}
  46.         t.flag=false;

  47.         Thread t2=new Thread(t);
  48.         t2.start();
  49.         }
  50. }
复制代码
不知道为什么,从头到尾都是0线程在运行,1线程没有运行?谢谢

评分

参与人数 1技术分 +1 收起 理由
袁梦希 + 1

查看全部评分

5 个回复

倒序浏览
锁应该在while里面的吧
  1. class Ticket implements Runnable

  2. {
  3.         private  int tick = 100;
  4.         Object obj = new Object();
  5.         boolean flag = true;

  6.         public void run() {
  7.                 if (flag) {
  8.                         while (true) {
  9.                                 synchronized (obj) {
  10.                                         if (tick > 0) {
  11.                                                 try {
  12.                                                         Thread.sleep(10);
  13.                                                 } catch (Exception e) {
  14.                                                 }
  15.                                                 System.out.println(Thread.currentThread().getName() + "....code : "
  16.                                                                 + tick--);
  17.                                         }
  18.                                 }
  19.                         }
  20.                 } else
  21.                         while (true)
  22.                                 show();
  23.         }

  24.         public  synchronized void show()

  25.         {
  26.                 if (tick > 0) {
  27.                         try {
  28.                                 Thread.sleep(10);
  29.                         } catch (Exception e) {
  30.                         }
  31.                         System.out.println(Thread.currentThread().getName() + "....show.... : " + tick--);
  32.                 }
  33.         }

  34. }

  35. public class TicketDemo
  36. {
  37.         public static void main(String[] args)
  38.         {
  39.                 Ticket t = new Ticket();
  40.                 Thread t1 = new Thread(t);
  41.                 Thread t2 = new Thread(t);
  42.                 t1.start();
  43.                 try {
  44.                         Thread.sleep(10);
  45.                 } catch (Exception e) {
  46.                 }
  47.                 t.flag = false;
  48.                 t2.start();
  49.         }
  50. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
袁梦希 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 刘学明    于 2013-5-15 23:29 编辑
  1. class Ticket implements Runnable
  2. {
  3.         private  int tick = 100;
  4.         Object obj = new Object();
  5.         boolean flag = true;
  6.         public void run() {
  7.                 if (flag) {
  8.                         while (true) {
  9.                                 synchronized (obj) {  //把锁定义在While循环的里面 因为如果定义在While外面 当Thread0进入同步锁以后然后就是一直是Thread0进行无限循环 直到把票卖完,Thread1也永远进不来。
  10.                                         if (tick > 0) {
  11.                                                 try {
  12.                                                         Thread.sleep(10);
  13.                                                 } catch (Exception e) {
  14.                                                 }
  15.                                                 System.out.println(Thread.currentThread().getName() + "....code : " + tick--);
  16.                                         }
  17.                                 }
  18.                         }
  19.                 } else
  20.                         while (true)
  21.                                 show();
  22.         }
  23.         public  synchronized void show()

  24.         {
  25.                 if (tick > 0) {
  26.                         try {
  27.                                 Thread.sleep(10);
  28.                         } catch (Exception e) {
  29.                         }
  30.                         System.out.println(Thread.currentThread().getName() + "....show.... : " + tick--);
  31.                 }
  32.         }

  33. }

  34. public class TicketDemo
  35. {
  36.         public static void main(String[] args)
  37.         {
  38.                 Ticket t = new Ticket();
  39.                 Thread t1 = new Thread(t);
  40.                 Thread t2 = new Thread(t);
  41.                 t1.start();
  42.                 try {
  43.                         Thread.sleep(10);
  44.                 } catch (Exception e) {
  45.                 }
  46.                 t.flag = false;
  47.                 t2.start();
  48.         }
  49. }
复制代码
回复 使用道具 举报
谢谢,大家原来是把锁定义在while循环外面了,呵呵,明白 了
回复 使用道具 举报
本帖最后由 librazeng 于 2013-5-16 00:16 编辑

不知道为什么,从头到尾都是0线程在运行,1线程没有运行?谢谢

答:如刘学明所言,要把同步代码块定义在while(true){}循环里面。你的代码问题出在:
  • synchronized(this)
  •         {
  •    while(flag==true && ticket>0)
  •           {
  •             try{Thread.sleep(10);}catch(Exception e){e.toString();}
  •            System.out.println(Thread.currentThread().getName()+"....."+ticket--);
  •         }
  • }


线程0拿到锁进来以后,一直在上面这个同步代码快中循环,直到ticket=0,也就是卖光了,ticket>0结果为false时,才跳出while循环,释放锁。主线程将flag改为false后,线程1过来调用show()方法,判断while(flag==false&&ticket>0)时,第二个表达式结果为false,所以不会进入循环,输出结果。

给我技术分啊啊啊啊啊{:soso_e109:}{:soso_e118:}
回复 使用道具 举报
librazeng 发表于 2013-5-16 00:12
不知道为什么,从头到尾都是0线程在运行,1线程没有运行?谢谢

答:如刘学明所言,要把同步代码块定义在while ...

哦,谢谢哥们啦,呵呵慢慢来面包还是会有的
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马