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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Friendy89 中级黑马   /  2013-4-6 12:08  /  1548 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 Friendy89 于 2013-4-7 00:03 编辑

class Ticket implements Runnable
{
        private int tick=100;
        public void run()
        {
                //for (tick=100;tick>0 ;tick-- )
                while(true)
                {
                        if (tick>0)
                        {
                                System.out.println(Thread.currentThread().getName()+"...sale..."+tick--);
                        }
                }
        }
}
class TicketDemo
{
        public static void main(String[] args)
        {
                Ticket t=new Ticket();

                Thread t1=new Thread(t); //创建一个线程。
                Thread t2=new Thread(t);
                Thread t3=new Thread(t);
                Thread t4=new Thread(t);
               
                t1.start();
                t2.start();
                t3.start();
                t4.start();
        }
}
程序中while循环为什么不能用for循环代替,我试了一下,运行结果会出现多个Thread-编号....sale.....100

评分

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

查看全部评分

6 个回复

倒序浏览
本帖最后由 张洪慊 于 2013-4-6 12:35 编辑

for (tick=100;tick>0 ;tick-- )//tick再次赋值为100
for( ; tick>0;tick--)//改正 我没测试 可能有别的错误
可能出现一种情况:
  1. class Ticket implements Runnable
  2. {
  3.          private int tick=100;
  4.          public void run()
  5.          {        //2.cpu切换到1线程,但是此时tick再次被赋值为100 下面会输出100
  6.                  //for (tick=100;tick>0 ;tick-- )
  7.                  while(true)
  8.                  {  
  9.                         
  10.                          if (tick>0)
  11.                          {      //1.cpu切换到0线程执行到这 此时tick=100,输出100,此时tick=99
  12.                                  System.out.println(Thread.currentThread().getName()+"...sale..."+tick--);
  13.                          }
  14.                  }
  15.          }
  16. }
复制代码

评分

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

查看全部评分

回复 使用道具 举报

class Ticket implements Runnable
{
        private int tick=100;
        public void run()
        {
                //for (tick=100;tick>0 ;tick-- )
                while(true)
                {
                        if (tick>0)
                        {
                                System.out.println(Thread.currentThread().getName()+"...sale..."+tick--);
                        }
                }
        }
}
class TicketDemo
{
        public static void main(String[] args)
        {
                Ticket t=new Ticket();

                Thread t1=new Thread(t); //创建一个线程。
                Thread t2=new Thread(t);
                Thread t3=new Thread(t);
                Thread t4=new Thread(t);
               
                t1.start();
                t2.start();
                t3.start();
                t4.start();
        }
}

---------------------------------------------------------------------------------------------------------
原因是这样的:
class Ticket 实现Runnable接口  则创建的线程使用的是同一个资源----类中的成员
当使用while(true)
System.out.println(Thread.currentThread().getName()+"...sale..."+tick--); tick是共同资源
而当使用for (tick=100;tick>0 ;tick-- )tick是局部的,是不共用,每个线程都可有一个,在执行时就会出现相同的结果。

评分

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

查看全部评分

回复 使用道具 举报
本帖最后由 刘吉庆 于 2013-4-6 12:48 编辑

当然可以替代,只是用的场景不同罢了,while用于不知道具体循环次数,而for多用于确定具体次数的循环。
代码我改为如下:
  1. package cn.bbs;

  2. class Ticket implements Runnable {
  3.         private int tick = 100;

  4.         public void run() {

  5.   //              while (true) {
  6.   //                    if (tick > 0) {
  7.   //                              System.out.println(Thread.currentThread().getName()
  8.   //                                             + "...sale..." + tick--);
  9.   //                      } else {
  10.   //                              break;//停止
  11.   //                      }
  12.   //              }
  13.                 for (; tick > 0;) {//第条新建线程start就会执行run()方法,因如你所写for (tick=100;tick>0 ;tick--),每次都会给重新赋值,tick--在输出语句已经减过,因此不必再减
  14.                         System.out.println(Thread.currentThread().getName() + "...sale..."
  15.                                         + tick--);
  16.                 }
  17.         }

  18. }

  19. public class TicketDemo {
  20.         public static void main(String[] args) {
  21.                 Ticket t = new Ticket();

  22.                 Thread t1 = new Thread(t); // 创建一个线程。
  23.                 Thread t2 = new Thread(t);
  24.                 Thread t3 = new Thread(t);
  25.                 Thread t4 = new Thread(t);

  26.                 t1.start();
  27.                 t2.start();
  28.                 t3.start();
  29.                 t4.start();
  30.         }
  31. }
复制代码

评分

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

查看全部评分

回复 使用道具 举报
因为在for循环中 ticket是局部变量 4个进程分别进来调用run方法时,找的ticket都是for循环中的,这时的ticket就不是共享资源。只要让ticket变成共享数据,就不会有多个sale...100了
将for(;tick>0;tick--)就可以了,因为已经定义了全局变量ticket=100了,所以不要在for条件中给ticket=100

评分

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

查看全部评分

回复 使用道具 举报
我对你的代码进行了修改和解释如下:
  1. class Ticket2 implements Runnable
  2. {
  3. Object obj=new Object();
  4. private int tick=100;
  5. public void run()
  6. {
  7. for (tick=100;tick>0 ; tick--)//控制票数的只有tick--
  8. // while(true)
  9. { synchronized(this){//考虑到线程安全问题,此处必须加同步代码块
  10. if (tick>0)
  11. {
  12. System.out.println(Thread.currentThread().getName()+"...sale..."+tick);//此处不必每次再减1

  13. }
  14. }
  15. }
  16. }
  17. }
  18. public class TestRunable
  19. {
  20. public static void main(String[] args)
  21. {
  22. Ticket2 t=new Ticket2();

  23. Thread t1=new Thread(t); //创建一个线程。
  24. Thread t2=new Thread(t);
  25. Thread t3=new Thread(t);
  26. Thread t4=new Thread(t);

  27. t1.start();
  28. t2.start();
  29. t3.start();
  30. t4.start();

  31. }

  32. }
复制代码

评分

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

查看全部评分

回复 使用道具 举报
请及时处理帖子,追问或改成【已解决】~ 至少让大家知道楼主在哦~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马