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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 要你快乐 中级黑马   /  2014-5-18 20:01  /  1114 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. public class BianLiangDemo implements Runnable{
  2.         int b=100;
  3.         public synchronized void m1()throws Exception{
  4.                 //Thread.sleep(5000);
  5.                 b=1000;
  6.                 System.out.println("m1 b="+b);
  7.         }
  8.         public synchronized void m2() throws Exception{
  9.                 Thread.sleep(2500);
  10.                 b=2000;
  11.                 System.out.println("m2 b="+b);
  12.         }
  13.         public void run(){
  14.                 try{
  15.                         m1();
  16.                 }catch(Exception e){e.printStackTrace();}
  17.         }
  18.         public static void main(String[] args)throws Exception  {
  19.                 BianLiangDemo t=new BianLiangDemo();
  20.                 Thread t1=new Thread(t);
  21.                 t1.start();
  22.                 t.m2();
  23.                 System.out.println("t="+t.b);
  24.         }
  25. }
复制代码
为什么输出结果是:m2 b=2000t=2000
m1 b=1000
而不是:m1 b=1000
m2 b=2000
t=2000呢?


评分

参与人数 1技术分 +1 收起 理由
张然龙 + 1

查看全部评分

7 个回复

倒序浏览
线程开启后 不会瞬间就有反应的
而主线程 毫无阻拦的往下运行 如果你给主线程sleep 就会看到你要的效果了吧
  1.         public static void main(String[] args) throws Exception {
  2.                 BianLiangDemo t = new BianLiangDemo();
  3.                 Thread t1 = new Thread(t);
  4.                 t1.start();
  5.                 Thread.sleep(1000);
  6.                 t.m2();
  7.                 System.out.println("t=" + t.b);
  8.         }
复制代码
回复 使用道具 举报
osully 发表于 2014-5-18 21:52
线程开启后 不会瞬间就有反应的
而主线程 毫无阻拦的往下运行 如果你给主线程sleep 就会看到你要的效果了吧 ...

但是如果不用synchronized修饰m1方法的话,就会先运行t1线程再运行主线程了。所以就是说如果m1加了synchronized就是主线程先往下执行吗?而且t1线程和主线程的优先级都是一样的中等级5呢!
回复 使用道具 举报
你把synchronized去掉后
m2 中的那个  Thread.sleep(2500); 就让主线程睡了
t1.start(); 这个线程就先运行了m1方法
如果你把所有sleep都去掉后 会发现  线程的运行是随机性的 因为他们在抢cpu的执行权

你是了解synchronized吗???
那就敲一敲生产和消费者
回复 使用道具 举报
osully 发表于 2014-5-19 08:30
你把synchronized去掉后
m2 中的那个  Thread.sleep(2500); 就让主线程睡了
t1.start(); 这个线程就先运行 ...

你的意思是m1()有synchronized,那么即使m2()有Thread.sleep(2500);也会继续执行,m1()没有了synchronized主线程就会毫无阻拦地往下运行?...
回复 使用道具 举报
我觉得问题都不在那些地方!!问题在于 public synchronized void m1()     public synchronized void m2()
这两个涵数的锁都调用的是本类对象BianLiangDemo.class,,就意味着这一同一把锁,,这两个涵不能同步运行,,任何一个函进入后别一个涵数都不能被调用,,,你那个程序中的两个线程生命周期都太短,,看不到效果,,如果把生命周期延长一点,,变成这样::
public class BianLiangDemo implements Runnable{
        int b=100;
        public synchronized void m1()throws Exception{
                //Thread.sleep(5000);
                b=1000;
                                for (int i=0;i<20 ;i++ )
                                {
                                         System.out.println("m1 b="+b);
                                }
        }
        public synchronized void m2() throws Exception{
                Thread.sleep(2500);
                b=2000;
                                for (int i=0;i<20 ;i++ )
                                {
                                        System.out.println("m2 b="+b);
                                }
        }
        public void run(){
                try{
                        m1();
                }catch(Exception e){e.printStackTrace();}
        }
        public static void main(String[] args)throws Exception  {
                BianLiangDemo t=new BianLiangDemo();
                Thread t1=new Thread(t);
                t1.start();
                                //Thread.sleep(10);
                t.m2();
                System.out.println("t="+t.b);
        }
}
你就会发现,,无论Thread.sleep();的值为多少,,System.out.println("m2 b="+b)这个均不能被打印,,因为主函数中的t.m1();一进入m1(),,副线程根本就进不去!!
如果你想要得到
m1 b=1000
m2 b=2000
t=2000呢?
可以在t.m2()前面加上Thread.sleep(10):让主线和小睡一会!程序代码就变成了;如下
public class BianLiangDemo implements Runnable{
        int b=100;
        public synchronized void m1()throws Exception{
                //Thread.sleep(5000);
                b=1000;
                System.out.println("m1 b="+b);
        }
        public synchronized void m2() throws Exception{
                //Thread.sleep(2500);
                b=2000;
                System.out.println("m2 b="+b);
        }
        public void run(){
                try{
                        m1();
                }catch(Exception e){e.printStackTrace();}
        }
        public static void main(String[] args)throws Exception  {
                BianLiangDemo t=new BianLiangDemo();
                Thread t1=new Thread(t);
                t1.start();
                Thread.sleep(10);
                t.m2();
                System.out.println("t="+t.b);
        }
}
这样,,其实也没能同步调用函数m1();和m2();因为这两个函数不能同步运行,,这行写只是给点时间,,让副线程先调用m1();副线程调用m1()后,主线程进t.m2(),就不能被调用,处于等待状待,,直到m()运行完后才执行!!,,

这是个人理解,,加上实验得出来的,,不知道对不对,,不过,,我花这么多时间来给你分析这问题,,怎么也给个技术分啊!!谢谢,,纯手打!!

评分

参与人数 1技术分 +1 收起 理由
张然龙 + 1

查看全部评分

回复 使用道具 举报
沉默的爱 发表于 2014-5-20 09:20
我觉得问题都不在那些地方!!问题在于 public synchronized void m1()     public synchronized void m2( ...

哥们儿,给力!{:2_35:}
回复 使用道具 举报

哈哈,,小菜一玫,,过奖了!!努力中,,想进36届!!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马