synchronized修飾普通方法,修飾靜態方法,修飾代碼塊,修飾線程run方法 比較
阿新 • • 發佈:2017-10-18
共享數據 比較 art text run best 初始 一個 lol
synchronized {普通方法}依靠對象鎖工作,多線程訪問synchronized方法,一旦某個進程搶得鎖之後,其他的進程只有排隊對待。 synchronized void method{}功能上,等效於 void method{ synchronized(this) { ... } } 通過代碼看比較清楚:
synchronized用於多線程設計,有了synchronized關鍵字,多線程程序的運行結果將變得可以控制。synchronized關鍵字用於保護共享數據。
synchronized實現同步的機制:synchronized依靠"鎖"機制進行多線程同步,"鎖"有2種,一種是對象鎖,一種是類鎖。
1.依靠對象鎖鎖定
初始化一個對象時,自動有一個對象鎖。synchronized {普通方法}依靠對象鎖工作,多線程訪問synchronized方法,一旦某個進程搶得鎖之後,其他的進程只有排隊對待。
synchronized {普通方法}依靠對象鎖工作,多線程訪問synchronized方法,一旦某個進程搶得鎖之後,其他的進程只有排隊對待。 synchronized void method{}功能上,等效於 void method{ synchronized(this) { ... } } 通過代碼看比較清楚:
public class TestSynchronized { public synchronized void method1() throws InterruptedException { System.out.println("method1 begin at:" + System.currentTimeMillis()); Thread.sleep(6000); System.out.println("method1 end at:" + System.currentTimeMillis()); } public synchronized void method2() throws InterruptedException { while(true) { System.out.println("method2 running"); Thread.sleep(200); } } static TestSychronized instance = new TestSychronized(); public static void main(String[] args) { Thread thread1 = new Thread(new Runnable() { @Override public void run() { try { instance.method1(); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=1; i<4; i++) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread1 still alive"); } } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { try { instance.method2(); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread1.start(); thread2.start(); } }
運行結果:thread2一直等到thread1中的method1執行完了之後才執行method2,說明method1和method2互斥
synchronized {修飾代碼塊}的作用不僅於此,synchronized void method{}整個函數加上synchronized塊,效率並不好。在函數內部,可能我們需要同步的只是小部分共享數據,其他數據,可以自由訪問,這時候我們可以用 synchronized(表達式){//語句}更加精確的控制。- 2.synchronized {static方法}此代碼塊等效於
package com.free4lab.lol; public class TestSychronized { public synchronized static void method1() throws InterruptedException { System.out.println("method1 begin at:" + System.currentTimeMillis()); Thread.sleep(6000); System.out.println("method1 end at:" + System.currentTimeMillis()); } public synchronized static void method2() throws InterruptedException { while(true) { System.out.println("method2 running"); Thread.sleep(200); } } static TestSychronized instance1 = new TestSychronized(); static TestSychronized instance2 = new TestSychronized(); public static void main(String[] args) { Thread thread1 = new Thread(new Runnable() { @Override public void run() { try { instance1.method1(); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=1; i<4; i++) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread1 still alive"); } } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { try { instance2.method2(); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread1.start(); thread2.start(); } }
輸出效果也是method1和method2互斥
- 3.synchronized {run方法}run方法的鎖定.
package com.free4lab.lol; public class TestSychronized { static TestSychronized instance = new TestSychronized(); public static void main(String[] args) { Thread thread1 = new Thread(new Runnable() { @Override public synchronized void run() { for(int i=1; i<4; i++) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread1 still alive, " + i); } } }); new Thread(thread1).start(); new Thread(thread1).start(); } }
如果加了synchronized當前線程取完所有數據後,才會釋放鎖,輸出結果是有序的
Thread1 still alive, 1 Thread1 still alive, 2 Thread1 still alive, 3 Thread1 still alive, 1 Thread1 still alive, 2 Thread1 still alive, 3
synchronized修飾普通方法,修飾靜態方法,修飾代碼塊,修飾線程run方法 比較