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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© HM许涛 中级黑马   /  2013-4-9 17:54  /  1502 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 HM许涛 于 2013-4-9 23:37 编辑

原题见张孝祥老师Java就业培训教程P195页5.2.4程序清单:ThreadDemo6.java
public class ThreadDemo6
{
        public static void main(String[] args)
        {
                ThreadTest t=new ThreadTest();
                new Thread(t).start();
                try
                {
                        Thread.sleep(1);
                }
                catch (Exception e)
                {
                }/**/
                t.str=new String("method");
                new Thread(t).start();
        }
}
class ThreadTest implements Runnable
{
        private int tickets=100;
        String str=new String(" ");
        public void run()
        {
                if(str.equals("method"))
                {
                        while(true)
                {
                        sale();
                }
                }
                else
                {
                        synchronized(str)
                        {
                                if(tickets>0)
                                {
                                        try
                                        {
                                                Thread.sleep(10);
                                        }
                                        catch (Exception e)
                                        {
                                                System.out.println(e.getMessage());
                                        }
                                        System.out.println(Thread.currentThread().getName()+"is saling aqaa   ticket "+tickets--);
        }
                        }
                }
                }

        public synchronized void sale()
        {
                if(tickets>0)
                {
                        try
                        {
                                Thread.sleep(10);
                        }
                        catch (Exception e)
                        {
                                System.out.println(e.getMessage());
                        }
                                System.out.println(Thread.currentThread().getName()+"is saling ticket "+tickets--);
                }
        }
}
这个例子调试了好多次,也百度了synchronized的语法,但是总是出不了书上写的效果,总是两个线程都调用sale方法,哪位大神帮忙看一下是哪里有问题?
书上给的效果应该是两个线程分别调用同步函数和同步代码块,并且最后一个线程打印结果为0.即两个没有同步。最后需要将STR替换成THIS才能实现同步。

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

5 个回复

倒序浏览
本帖最后由 李罡 于 2013-4-9 19:49 编辑
  1. package cn.itcast.day1;

  2. public class ThreadDemo6
  3. {
  4.         public static void main(String[] args)
  5.        {
  6.                 ThreadTest t=new ThreadTest();
  7.                 new Thread(t).start();
  8.                 try
  9.                 {
  10.                         Thread.sleep(1);
  11.                 }
  12.                 catch (Exception e)
  13.                 {
  14.                 }/**/
  15.                 t.str=new String("method");
  16.                 new Thread(t).start();
  17.         }
  18. }
  19. class ThreadTest implements Runnable
  20. {
  21.         private int tickets=100;
  22.         String str=new String(" ");
  23.         public void run()
  24.         {
  25.                 if(str.equals("method"))
  26.                 {
  27.                         while(true)
  28.                         {
  29.                         sale();
  30.                         }
  31.                 }
  32.                 else
  33.                 {
  34.                         while(true){//此处加上while(true)即可,不加的话,第一个线程只打印一次就执行完了,就只剩下另外一个线程在执行,所以最后面的一个是1而不是0
  35.                         synchronized(str)
  36.                         {
  37.                                 if(tickets>0)
  38.                                 {
  39.                                         try
  40.                                         {
  41.                                                 Thread.sleep(10);
  42.                                         }
  43.                                         catch (Exception e)
  44.                                         {
  45.                                                 System.out.println(e.getMessage());
  46.                                         }
  47.                                         System.out.println(Thread.currentThread().getName()+"is saling aqaa   ticket "+tickets--);
  48.         }
  49.                         }
  50.                         }
  51.                 }
  52.                 }

  53.        public synchronized void sale()
  54.        {
  55.                 if(tickets>0)
  56.                 {
  57.                         try
  58.                         {
  59.                                 Thread.sleep(10);
  60.                         }
  61.                         catch (Exception e)
  62.                         {
  63.                                 System.out.println(e.getMessage());
  64.                         }
  65.                                 System.out.println(Thread.currentThread().getName()+"is saling ticket "+tickets--);
  66.                 }
  67.         }
  68. }
  69. 如上所示,在第35行处加上while(true),加上后,因为两个线程用得不是同一个锁,线程不同步,最后打印结果为0
复制代码

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
李罡 发表于 2013-4-9 19:46

收到,感谢哈。原来是这个问题,呜呜,张老师的书有些地方要修订一下了。
回复 使用道具 举报
李罡 发表于 2013-4-9 19:46

修改后使用THIS代替STR貌似也得不到同步的效果………………
回复 使用道具 举报
HM许涛 发表于 2013-4-9 21:34
修改后使用THIS代替STR貌似也得不到同步的效果………………

我试了,可以得到同步的效果啊!后面打印的是1而不是0.
你把Ticket改为1000试试,100有点少有可能看不到你所想看到的结果!


回复 使用道具 举报
李罡 发表于 2013-4-9 23:31
我试了,可以得到同步的效果啊!后面打印的是1而不是0.
你把Ticket改为1000试试,100有点少有可能看不到 ...

呵呵,是的,换了大数试了下对了。感谢哈。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马