【問題描述】關於Java中synchronized 用在實例方法和對象方法上面的區別
【問題分析】大家都知道,在Java中,synchronized 是用來表示同步的,我們可以synchronized 來修飾一個方法(實例方法和類方法---注:不知道這樣叫準確不準確,大家理解我的意識就行了)。也可以synchronized 來修飾方法裏面的一個語句塊。
修飾實例方法:
- public synchronized void x() throws InterruptedException
- {
- for (int i = 0; i < 10; i++)
- {
- Thread.sleep(1000);
- System.out.println("x.......................");
- }
- }
修飾類方法(static 方法):
- public static synchronized void staticX() throws InterruptedException
- {
- for (int i = 0; i < 10; i++)
- {
- Thread.sleep(1000);
- System.out.println("staticX.......................");
- }
- }
修飾方法裏面語句塊:
- public static void staticX() throws InterruptedException
- {
- synchronized (locks)
- {
- for (int i = 0; i < 10; i++)
- {
- Thread.sleep(1000);
- System.out.println("staticX.......................");
- }
- }
- }
注意:這裏不能用synchronized修飾方法外面的語句塊(我把他叫做類語句塊),雖然我們可以在方法外面定義語句塊,這樣做會遇到編譯錯誤,這裏涉及到了Java裏面的對象初始化的部分知識。大概的原因就是synchronized鎖住的是對象,當初始化對象的時候,JVM在對象初始化完成之前會調用方法外面的語句塊,這個時候對象還不存在,所以就不存在鎖了。
那麼,在static方法和非static方法前面加synchronized到底有什麼不同呢?
大家都知道,static的方法屬於類方法,它屬於這個Class(注意:這裏的Class不是指Class的某個具體對象),那麼static獲取到的鎖,就是當前調用這個方法的對象所屬的類(Class,而不再是由這個Class產生的某個具體對象了)。而非static方法獲取到的鎖,就是當前調用這個方法的對象的鎖了。所以,他們之間不會產生互斥。
看代碼:
- package com.jack.zhang.chapter9.classlock;
- /**
- * @author Jack Zhang
- * @version vb1.0
- * @Email [email protected]
- * @Date 2012-5-20
- */
- public class Test
- {
- public static synchronized void staticX() throws InterruptedException
- {
- for (int i = 0; i < 10; i++)
- {
- Thread.sleep(1000);
- System.out.println("staticX.......................");
- }
- }
- public synchronized void x() throws InterruptedException
- {
- for (int i = 0; i < 10; i++)
- {
- Thread.sleep(1000);
- System.out.println("x.......................");
- }
- }
- public static void main(String[] args)
- {
- final Test test1 = new Test();
- Thread thread = new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- test1.x();
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }, "a");
- Thread thread1 = new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- Test.staticX();
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }, "b");
- thread1.start();
- thread.start();
- }
- }
運行結果是:
- staticX.......................
- x.......................
- x.......................
- staticX.......................
- staticX.......................
- x.......................
- x.......................
- staticX.......................
- x.......................
- staticX.......................
- staticX.......................
- x.......................
- x.......................
- staticX.......................
- x.......................
- staticX.......................
- x.......................
- staticX.......................
- x.......................
- staticX.......................
那當我們想讓所有這個類下面的對象都同步的時候,也就是讓所有這個類下面的對象共用同一把鎖的時候,我們如何辦呢?
看代碼:
- package com.jack.zhang.chapter9.classlock;
- /**
- * @author Jack Zhang
- * @version vb1.0
- * @Email [email protected]
- * @Date 2012-5-20
- */
- public class Test
- {
- public final static Byte[] locks = new Byte[0];
- public static void staticX() throws InterruptedException
- {
- synchronized (locks)
- {
- for (int i = 0; i < 10; i++)
- {
- Thread.sleep(1000);
- System.out.println("staticX.......................");
- }
- }
- }
- public void x() throws InterruptedException
- {
- synchronized (locks)
- {
- for (int i = 0; i < 10; i++)
- {
- Thread.sleep(1000);
- System.out.println("x.......................");
- }
- }
- }
- public static void main(String[] args)
- {
- final Test test1 = new Test();
- final Test test2 = new Test();
- Thread thread = new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- test1.x();
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }, "a");
- Thread thread1 = new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- Test.staticX();
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }, "b");
- thread1.start();
- thread.start();
- }
- }
運行結果:
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- staticX.......................
- x.......................
- x.......................
- x.......................
- x.......................
- x.......................
- x.......................
- x.......................
- x.......................
- x.......................
- x.......................
轉載:http://blog.csdn.net/virgoboy2004/article/details/7585182