黑马程序员技术交流社区

标题: 关于代码块与函数间的同步问题 [打印本页]

作者: HM许涛    时间: 2013-4-9 17:54
标题: 关于代码块与函数间的同步问题
本帖最后由 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才能实现同步。
作者: 李罡    时间: 2013-4-9 19:46
本帖最后由 李罡 于 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
复制代码

作者: HM许涛    时间: 2013-4-9 21:32
李罡 发表于 2013-4-9 19:46

收到,感谢哈。原来是这个问题,呜呜,张老师的书有些地方要修订一下了。
作者: HM许涛    时间: 2013-4-9 21:34
李罡 发表于 2013-4-9 19:46

修改后使用THIS代替STR貌似也得不到同步的效果………………
作者: 李罡    时间: 2013-4-9 23:31
HM许涛 发表于 2013-4-9 21:34
修改后使用THIS代替STR貌似也得不到同步的效果………………

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



作者: HM许涛    时间: 2013-4-9 23:36
李罡 发表于 2013-4-9 23:31
我试了,可以得到同步的效果啊!后面打印的是1而不是0.
你把Ticket改为1000试试,100有点少有可能看不到 ...

呵呵,是的,换了大数试了下对了。感谢哈。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2