1.修飾在方法上,多個線程調用同一個對象的同步方法會阻塞,調用不一樣對象的同步方法不會阻塞。(java對象的內存地址是否相同)java
public synchronized void obj3() { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } }
2.修飾代碼塊,這個this就是指當前對象(類的實例),多個線程調用同一個對象的同步方法會阻塞,調用不一樣對象的同步方法不會阻塞。(java對象的內存地址是否相同)多線程
public void obj2() { synchronized (this) { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } }
3.修飾代碼塊,這個str就是指String對象,多個線程調用同一個對象的同步方法會阻塞,調用不一樣對象的同步方法不會阻塞。(java對象的內存地址是否相同)ide
public void obj2() { String str=new String("lock");//在方法體內,調用一次就實例化一次,多線程訪問不會阻塞,由於不是同一個對象,鎖是不一樣的 synchronized (str) { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } }
public static void main(String[] args) throws InterruptedException { test test=new test(); new Thread(new Runnable() { @Override public void run() { test.obj2(); } }).start(); new Thread(new Runnable() { @Override public void run() { test.obj2(); } }).start(); }
//兩個方法之間交替執行 沒有阻塞
Thread-0 : 4
Thread-1 : 4
Thread-1 : 3
Thread-0 : 3
Thread-1 : 2
Thread-0 : 2
Thread-1 : 1
Thread-0 : 1
Thread-0 : 0
Thread-1 : 0
共用一個對象,多線程調用obj2同步方法,由於使用的是一個對象鎖,會阻塞。this
String str=new String("lock"); //對象放在方法外,調用方法的時候不會新建立一個對象。 public void obj2() { synchronized (str) { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } }
Thread-0 : 4
Thread-0 : 3
Thread-0 : 2
Thread-0 : 1
Thread-0 : 0
Thread-1 : 4
Thread-1 : 3
Thread-1 : 2
Thread-1 : 1
Thread-1 : 0
1.Synchronized修飾靜態的方法spa
public static synchronized void obj3() { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } }
2.synchronized (test.class) ,鎖的對象是test.class,即test類的鎖。線程
public void obj1() { synchronized (test.class) { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } }
那麼問題來了:在一個類中有兩方法,分別用synchronized 修飾的靜態方法(類鎖)和非靜態方法(對象鎖)。多線程訪問兩個方法的時候,線程會不會阻塞?code
public static synchronized void obj3() { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } public synchronized void obj4() { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } }
答案是???對象
Thread-0 : 4
Thread-1 : 4
Thread-0 : 3
Thread-1 : 3
Thread-1 : 2
Thread-0 : 2
Thread-1 : 1
Thread-0 : 1
Thread-1 : 0
Thread-0 : 0blog
到這麼咱們應該知道了:內存
1,要知足方法同步(或者代碼塊同步)就必須保證多線程訪問的是同一個對象(在java內存中的地址是否相同)。
2,類鎖和對象鎖同時存在時,多線程訪問時不會阻塞,由於他們不是一個鎖。
----------------------------------------------------------------------------------------------------------------
理解不到位的地方,煩請指出來。