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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 土突突 中级黑马   /  2014-4-26 12:13  /  1075 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 土突突 于 2014-4-27 12:10 编辑
  1. class  ThreadDemo
  2. {
  3.              public static void main(String[] args)
  4.                {
  5.                    Test t=new Test();
  6.                    Thread th1=new Thread(t);
  7.                    Thread th2=new Thread(t);
  8.                    th1.start();
  9.                    try{Thread.sleep(10);} catch(Exception e){}
  10.                    t.flag=false;
  11.                    th2.start();
  12.               }
  13. }
  14. class Test implements Runnable
  15. {
  16.            boolean flag=true;
  17.            int ticket=100;
  18.            Object o=new Object();
  19.            public void run()
  20.              {
  21.                 if(flag)
  22.                   {
  23.                         while(true)
  24.                           {
  25.                                   synchronized(o)
  26.                                     {
  27.                                           if(ticket>0)
  28.                                              {
  29.                                                    try{Thread.sleep(10);} catch(Exception e){}
  30.                                                    System.out.println("ticket synchronized-------"+(ticket--));
  31.                                              }
  32.                                      }
  33.                            }
  34.                  }
  35.                else
  36.                   {
  37.                        while(true)
  38.                        show();
  39.                   }
  40.                }
  41.              public synchronized void show()
  42.                {
  43.                    if(ticket>0)
  44.                         {
  45.                              try{Thread.sleep(10);} catch(Exception e){}
  46.                              System.out.println("ticket void show()---"+(ticket--));
  47.                         }
  48.                }
  49.         
  50. }
复制代码
发现一个问题,每次我写成synchronized(o)时即使出现打印不合理的情况,但每次两个线程都能保证交替执行,可是当我换成正确情况synchronized(this)的时候,虽然打印正确,但每次都是一个线程在运行。我都试了n次了,一直没有出现两个线程交替执行的情况。要么是一直在打印ticket synchronized-------,要么是前半部分打印ticket synchronized-------,后半部分打印ticket void show()---,是不是我哪写错了还是我的电脑真给我杠上了,求解答......

评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

4 个回复

正序浏览
向日葵的曙光 发表于 2014-4-26 14:43
show方法必须定义成静态方法,不然你连调用都是错的
public synchronized void show()
               {

show方法没必要定义成静态的吧?
回复 使用道具 举报
miedongdong 发表于 2014-4-26 16:13
刚刚看了一下多线程的知识,发现你的代码出现在毕老师视频《验证同步方法的锁是this》中,当时说到代码要实 ...

你的解释很合理,谢谢
回复 使用道具 举报
刚刚看了一下多线程的知识,发现你的代码出现在毕老师视频《验证同步方法的锁是this》中,当时说到代码要实现同步,要达成两个条件:
1、两个或者两个线程以上(这个符合)
2、必须是同一个锁

你说当synchronized(0)的时候会打印不合理情况,就是代码还没同步,所以才不合理,而将o改为this,打印数据合理了,也就是说代码这时已经同步了。但是打印出来的数据却没按照你预想的方向走,那就应该跟cpu的执行机制有关了,不过总体来说也是交叉执行的,也许10毫秒对于计算机已经是很久了呢~~

我在你的代码中添加了两句:

  1. <p>  public void run()
  2.              {
  3.                 if(flag)
  4.                   {
  5.                         while(true)
  6.                           {
  7.                                   synchronized(o)
  8.                                     {
  9.                                           if(ticket>0)
  10.                                              {
  11.              System.out.println("sysnchronized--i===:"+ (++i));//第一句
  12.                                                    try{Thread.sleep(5);} catch(Exception e){}
  13.                                                    System.out.println("ticket synchronized-------"+(ticket--));
  14.                                              }
  15.                                      }
  16.                            }
  17.                  }
  18.                else
  19.                   {
  20.       System.out.println("show--i:"+ (++i));//第二句
  21.                        while(true)
  22.                        show();
  23.                   }
  24.                }</p>
复制代码

通过打印结果是第一句先执行,再执行第二句,之后就是一大堆一大堆的执行了,应该是电脑在10毫秒中就可以打印这么多了。希望能帮到你

评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

回复 使用道具 举报
show方法必须定义成静态方法,不然你连调用都是错的
public synchronized void show()
               {
                   if(ticket>0)
                        {
                             try{Thread.sleep(10);} catch(Exception e){}
                             System.out.println("ticket void show()---"+(ticket--));
                        }
               }

评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

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