黑马程序员技术交流社区

标题: java线程锁的问题 ?? [打印本页]

作者: 荣天    时间: 2012-5-23 12:42
标题: java线程锁的问题 ??
  1. public class TT implements Runnable {
  2. int b = 100;

  3. public synchronized void m1() throws Exception{
  4.   //Thread.sleep(2000);
  5.   b = 1000;
  6.   Thread.sleep(5000);
  7.   System.out.println("b = " + b);
  8. }

  9. public synchronized void m2() throws Exception {
  10.   Thread.sleep(2500);
  11.   b = 2000;
  12. }

  13. public void run() {
  14.   try {
  15.    m1();
  16.   } catch(Exception e) {
  17.    e.printStackTrace();
  18.   }
  19. }

  20. public static void main(String[] args) throws Exception {
  21.   TT tt = new TT();
  22.   Thread t = new Thread(tt);
  23.   t.start();
  24.   
  25.   tt.m2();
  26.   System.out.println(tt.b);
  27. }
  28. }
复制代码
为什么是m2()执行先而不是m1()执行先呢?如果m2()如掉synchronized 又是怎么样了 ?赐教  谢谢
作者: 黄奕豪    时间: 2012-5-23 13:12
本帖最后由 黄奕豪 于 2012-5-23 13:15 编辑

为什么是m2()先执行?因为m2()是主线程执行的,当主线程启动t.start();时,还没等t线程启动完执行他的run方法,他就已经执行下一句:tt.m2();了,至于后面一个问题说明一下吧;按照下面的代码改一下代码测试一下!
public class TT implements Runnable
{
        int b = 100;
        public synchronized void m1() throws Exception
        {         
          //Thread.sleep(2000);
                while(true) //加循环
                {
                  b = 1000;                 
                  Thread.sleep(50);                 
                  System.out.println("b = " + b);
                }
        }
         

        public synchronized void m2() throws Exception
        {
                while(true)//加循环,把主线程的打印调上这里
                {
                 Thread.sleep(25);         
                 b = 2000;
                 System.out.println(b);
                }
        }
        public void run()
        {         
                try
                {         
                        m1();         
                }
                catch(Exception e)
                {         
                        e.printStackTrace();
                }         
        }
        public static void main(String[] args) throws Exception
        {
                  TT tt = new TT();                 
                  Thread t = new Thread(tt);                 
                  t.start();
                  tt.m2();
        }
}
当你运行的时候吧,你是不是发现一直都是m2()在打印?m1()根本就没动过,因为在这里你已经将主线程和tt线程同步了,而且刚才也说了,主线程先开始执行的tt对象中的方法的,所以它先获得了tt锁(synchronized修饰函数的时候,默认的锁是this)的通行证,主线程调用tt对象狂打印,一直不出来,而tt线程也就进不去,所以只有主线程调用的m2()方法在运行打印,而去掉synchronized以后吧,就没有锁了,主线程可以用tt对象,tt线程也可以用tt对象,所以就出现了交替打印的现象了!!你多试验一下,看是不是跟我说的一样!!本人粗浅之见,如果有错,还希望多多交流!!本人也是菜鸟一枚~!
作者: 游兴钟    时间: 2012-5-23 14:28
本帖最后由 achilles 于 2012-5-23 14:34 编辑

m1()和m2()分别由t线程和主线程调用的。
m1()方法一执行睡5秒,m2()方法睡2.5秒,这里和锁没什么关系,无论谁一睡就会自动释放执行器和锁。程序一执行的结果是两个线程都睡过去了,但主线程因为睡的时间短,先醒了,这时t线程还睡着呢。
楼主想要m1()先执行很简单,把sleep的时间对调就可以。




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