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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

﹌★ㄊ蕾oo-

黑马帝

  • 黑马币:0

  • 帖子:5

  • 精华:0

© ﹌★ㄊ蕾oo- 黑马帝   /  2011-10-16 13:00  /  1711 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

评分

参与人数 1技术分 +1 收起 理由
宁超 + 1 赞一个!

查看全部评分

3 个回复

正序浏览
如果这个对象中有多个方法都上了锁,而且上锁的方法中内部调用了wait,那有wait的线程执行到wait会释放执行权给其他上锁的线程.

评分

参与人数 1技术分 +1 收起 理由
宁超 + 1 很给力!

查看全部评分

回复 使用道具 举报
宁超 黑马帝 2011-10-16 22:28:38
藤椅
这个要看是同步方法还是非同步方法了。
如果是同步方法的话是不可以的。
如果是非同步方法的话是可以的。
我用代码来演示下。
  1. package Test;

  2. public class Test1
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 ThreadDemo threadDemo=new ThreadDemo();
  7.                 Thread t1=new ThreadOne(threadDemo);
  8.                 Thread t2=new ThreadTwo(threadDemo);
  9.                 Thread t3=new ThreadThree(threadDemo);
  10.                 t1.start();
  11.                 t2.start();
  12.                 t3.start();

  13.         }

  14. }

  15. class ThreadDemo
  16. {

  17.         public synchronized void method1()
  18.         {
  19.                 for (int i = 0; i < 10; i++)
  20.                 {
  21.                         try
  22.                         {
  23.                                 Thread.sleep(500);
  24.                         } catch (InterruptedException e)
  25.                         {
  26.                                 e.printStackTrace();
  27.                         }
  28.                         System.out.println("同步方法1"+"    "+ i);
  29.                 }
  30.         }

  31.         public synchronized void method2()
  32.         {
  33.                 for (int i = 0; i < 10; i++)
  34.                 {
  35.                         try
  36.                         {
  37.                                 Thread.sleep(500);
  38.                         } catch (InterruptedException e)
  39.                         {
  40.                                 e.printStackTrace();
  41.                         }
  42.                         System.out.println("同步方法2"+"    " + i);
  43.                 }
  44.         }

  45.         public void Print()
  46.         {
  47.                 for (int i = 0; i < 10; i++)
  48.                 {
  49.                         try
  50.                         {
  51.                                 Thread.sleep(500);
  52.                         } catch (InterruptedException e)
  53.                         {
  54.                                 e.printStackTrace();
  55.                         }
  56.                         System.out.println("非同步方法" + i);
  57.                 }
  58.         }
  59. }

  60. class ThreadOne extends Thread
  61. {
  62.         private ThreadDemo threadDemo;

  63.         public ThreadOne(ThreadDemo threadDemo)
  64.         {
  65.                 this.threadDemo = threadDemo;
  66.         }

  67.         public void run()
  68.         {
  69.                 this.threadDemo.method1();
  70.         }
  71. }

  72. class ThreadTwo extends Thread
  73. {
  74.         private ThreadDemo threadDemo;

  75.         public ThreadTwo(ThreadDemo threadDemo)
  76.         {
  77.                 this.threadDemo = threadDemo;
  78.         }

  79.         public void run()
  80.         {
  81.                 this.threadDemo.method2();
  82.         }
  83. }

  84. class ThreadThree extends Thread
  85. {
  86.         private ThreadDemo threadDemo;

  87.         public ThreadThree(ThreadDemo threadDemo)
  88.         {
  89.                 this.threadDemo = threadDemo;
  90.         }

  91.         public void run()
  92.         {
  93.                 this.threadDemo.Print();
  94.         }

  95. }
复制代码
定义ThreadDemo类 有三个方法metho1,method2,Print。
其中metho1,method2为同步方法。Print为非同步方法。
如果在主函数中只开启t1.start()和t2.start();则输出结果为
t1输出完后,t2在输出。所以如果是同步方法的话是不可以的。

如果在主函数中只开启t1.start()和t3.start();则输出结果为
t1,Print交替输出。所以如果是非同步方法的话是可以的。
回复 使用道具 举报
可以。
Java 中的每个对象都有一个锁,当访问某个对象的synchronized方法时,表示将该对象上锁,
此时其他任何线程都无法访问该synchronized方法了,直到之前的那个线程方法完毕或是抛出了异常,
则该对象将锁释放掉,其他线程才可能去访问该synchronized方法。
如果一个对象有多个synchronized方法,某个线程已经进入到了某个synchronized方法,在该方法没有执行
完毕前,其他线程无法访问该对象的任何synchronized方法,但其它线程可进入此对象的其它方法。

请运行示例:
public class MyThreadTest
{
        public static void main(String[] args)
        {
                Demo example = new Demo();

                Thread t1 = new TheThread33(example);

                Thread t2 = new TheThread44(example);

                Thread t3 = new TheThread55(example);

                t1.start();
                t2.start();
                t3.start();
        }
}

class Demo
{
        public synchronized void execute()
        {
                for (int i = 0; i < 10; i++)
                {
                        try
                        {
                                Thread.sleep(500);
                        }
                        catch (InterruptedException e)
                        {
                                e.printStackTrace();
                        }

                        System.out.println("hello: " + i);
                }
        }

        public synchronized void execute2()
        {
                for (int i = 0; i < 10; i++)
                {
                        try
                        {
                                Thread.sleep(500);
                        }
                        catch (InterruptedException e)
                        {
                                e.printStackTrace();
                        }

                        System.out.println("world: " + i);
                }
        }

        public void output()
        {
                for (int x = 0; x < 10; x++)
                {
                        try
                        {
                                Thread.sleep(600);
                        }
                        catch (InterruptedException e)
                        {
                                e.printStackTrace();
                        }
                        System.out.println("你好啊");
                }
        }

}

class TheThread33 extends Thread
{
        private Demo example;

        public TheThread33(Demo example)
        {
                this.example = example;
        }

        @Override
        public void run()
        {
                this.example.execute();
        }
}

class TheThread44 extends Thread
{
        private Demo example;

        public TheThread44(Demo example)
        {
                this.example = example;
        }

        @Override
        public void run()
        {
                this.example.output();
        }
}

class TheThread55 extends Thread
{
        private Demo example;

        public TheThread55(Demo example)
        {
                this.example = example;
        }

        @Override
        public void run()
        {
                this.example.execute2();
        }
}

评分

参与人数 1技术分 +2 收起 理由
宁超 + 2 很详细。圣思园的门徒吧?

查看全部评分

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