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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 崔朋朋 中级黑马   /  2012-9-6 21:26  /  1814 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文


public class T implements Runnable {
        int a=0;
       
        @Override
        public void run()
        {
                m1();
        }

        //方法m1
        public synchronized void m1()
        {
                a=1;
                try {
                        Thread.sleep(6000);
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
                System.out.println("m1:a="+a);
        }
       
        //方法m2
        public void m2()
        {
                System.out.println("m2:a="+a);
        }

        //main方法
        public static void main(String[] args) throws Exception
        {
                T r1=new T();
                Thread t=new Thread(r1);
                t.start();
               
                Thread.sleep(2000);//保证线程t的run()方法执行
                r1.m2();
        }
       
        问题如下:
        当执行完t.start();后   对象r1被锁定,为什么还能调用对象r1的m2()方法?
       
        最终执行结果如下:
        m2:a=1
        m1:a=1

评分

参与人数 1技术分 +1 收起 理由
王德升 + 1 赞一个!

查看全部评分

5 个回复

倒序浏览
本帖最后由 杨震 于 2012-9-6 21:54 编辑

这个是因为你m2方法没有加锁

public class T implements Runnable {
         int a=0;
         
        @Override
         public void run()
         {
                 m1();
         }

        //方法m1
         public synchronized void m1()
         {
                 a=1;
                 try {
                         Thread.sleep(6000);
                 } catch (InterruptedException e) {
                         e.printStackTrace();
                 }
                 System.out.println("m1:a="+a);
         }
         
        //方法m2
         public synchronized void m2()   //这里需要加个锁;加锁表示执行前需要看下this对象是否已经被锁,如果被锁不能执行;你没有加锁,执行他之前也就不需要查看对象是否被锁,也就是说,你不加synchronized的话,就算this对象锁了,方法也可以执行
         {
                 System.out.println("m2:a="+a);
         }

        //main方法
         public static void main(String[] args) throws Exception
         {
                 T r1=new T();
                 Thread t=new Thread(r1);
                 t.start();
                 
                Thread.sleep(2000);//保证线程t的run()方法执行
                 r1.m2();
         }
}

评分

参与人数 1技术分 +1 收起 理由
王德升 + 1 赞一个!

查看全部评分

回复 使用道具 举报
楼主你试下,加个synchronized以的,就是先执行m1,后执行m2了
回复 使用道具 举报
楼上正解
如果锁对象拥有同步和非同步方法,则非同步方法可以被多个线程自由访问而不受锁的限制。
回复 使用道具 举报
public class T implements Runnable {
        int a=0;
        
        @Override
        public void run()
        {
                m1();
        }

        //方法m1
        public synchronized void m1()
        {
                a=1;
                try {
                        Thread.sleep(6000);
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
                System.out.println("m1:a="+a);
        }
        
        //方法m2
        public void m2()
        {
                System.out.println("m2:a="+a);
        }

        //main方法
        public static void main(String[] args) throws Exception
        {
                T r1=new T();
                Thread t=new Thread(r1);
                t.start();
               
                Thread.sleep(2000);//保证线程t的run()方法执行
                r1.m2();
        }
        
        问题如下:
        当执行完t.start();后   对象r1被锁定,为什么还能调用对象r1的m2()方法?
        解答:这里涉及到多线程知识,r1是一个线程,没有对象去和他竞争资源所以并不妨碍r1.m2()的方法!
线程锁的总结:
        1.当两个以上的线程同时访问同一个对象object中的这个synchronized(this)同步代码块时,这段代码这段时间只能有一个线程访问。其他线程必须等待当前线程执行完这段代码块后才能执行该代码块
        2.当一个线程访问object的一个synchronized(this)代码块时,其他线程仍可以访问object中的非同步代码块


回复 使用道具 举报
嗯,看来大家对多线程的理解都蛮透彻的,都是正确答案.
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马