synchronized修饰静态方法与实例方法
生活随笔
收集整理的這篇文章主要介紹了
synchronized修饰静态方法与实例方法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、synchronized修飾實例方法:
synchronized修飾實例方法,實際上是對調用該方法的對象加鎖。
場景1:同一實例對象在兩個線程中分別調用該對象的兩個同步實例方法
public class Car {public synchronized void runing1(Thread thread){System.out.println(thread.getName()+ " car1 得到鎖");System.out.println("------ car1 is running ------");working();System.out.println(thread.getName()+ " car1 釋放鎖");System.out.println();}public synchronized void runing2(Thread thread){System.out.println(thread.getName()+ " car2 得到鎖");System.out.println("------ car2 is running ------");working();System.out.println(thread.getName()+ " car2 釋放鎖");System.out.println();}public static void working(){try{Thread.sleep(1000);}catch(InterruptedException e){e.printStackTrace();}} } public class Test01 {public static void main(String[] args) {Car car = new Car();//線程1Thread t1 = new Thread(){@Overridepublic void run() {car.runing1(Thread.currentThread()); //同步實例方法1}};t1.start();//線程2Thread t2 = new Thread(){@Overridepublic void run() {car.runing2(Thread.currentThread()); //同步實例方法2}};t2.start();} }結果:兩個線程依次執行,說明產生互斥,因為實例方法加鎖針對的是實例對象,當前對象調用?一個synchronized方法時,其他同步方法需要等待其執行結束并釋放鎖之后才能執行。
場景二:兩個對象在兩個線程中分別調用同一個?同步實例方法
public class test02 {public static void main(String[] args) {Car car1 = new Car();Car car2 = new Car();//線程1 對象1Thread t1 = new Thread(){@Overridepublic void run() {car1.runing1(Thread.currentThread()); //同步實例方法1}};t1.start();//線程2 對象2Thread t2 = new Thread(){@Overridepublic void run() {car2.runing1(Thread.currentThread()); //同步實例方法1}};t2.start();} }結果 :兩個線程同時進行,因為是兩個對象,實例方法加鎖針對的是實例對象,并不是方法,所以可以并發執行,不會互斥。
此外,同一個對象分別在兩個線程中分別調用同步實例方法和非同步方法(未用synchronized修飾的方法),不會出現互斥,這里不再展示。synchronized關鍵字可以保證被它修飾的方法或者代碼塊在任意時刻只能有一個線程執行,而不會限制其他非synchronized方法。非synchronized方法不需要占有該對象,因此不會互斥。
synchronized修飾類方法:
synchronized修飾靜態方法,實際上是對該類進行加鎖,而不屬于某個對象。
場景一:用類直接在兩個線程中調用兩個不同的同步靜態方法
public class Car {public static synchronized void staticRuning1(Thread thread){System.out.println(thread.getName()+ " static car1 得到鎖");System.out.println("------ static car1 is running ------");working();System.out.println(thread.getName()+ " static car1 釋放鎖");System.out.println();}public static synchronized void staticRuning2(Thread thread){System.out.println(thread.getName()+ " static car2 得到鎖");System.out.println("------ static car2 is running ------");working();System.out.println(thread.getName()+ " static car2 釋放鎖");System.out.println();}public static void working(){try{Thread.sleep(1000);}catch(InterruptedException e){e.printStackTrace();}} } public class test02 {public static void main(String[] args) {//線程1 類Thread t1 = new Thread(){@Overridepublic void run() {Car.staticRuning1(Thread.currentThread()); //同步類方法1}};t1.start();//線程2 類Thread t2 = new Thread(){@Overridepublic void run() {Car.staticRuning2(Thread.currentThread()); //同步類方法2}};t2.start();} }結果:產生互斥,因為對靜態方法加鎖,實際上是對類加鎖,類只有一個。因此當一個同步靜態方法被訪問時,該類已處于被鎖狀態。此時其他同步靜態方法不能被訪問?(未用synchronized修飾的靜態方法仍可以訪問)
場景二:兩個線程分別調用同步類方法和同步實例方法
public class test03 {public static void main(String[] args) {Car car = new Car();//線程1 實例對象Thread t1 = new Thread(){@Overridepublic void run() {car.runing1(Thread.currentThread()); //同步實例方法1}};t1.start();//線程2 類Thread t2 = new Thread(){@Overridepublic void run() {Car.staticRuning2(Thread.currentThread()); //同步類方法2 //面試中一個面試官問如果靜態方法通過實例來調用,那鎖的是實例還是類呢?//當然還是類了,這里可以把Car.staticRuning2改成car.staticRuning2,通過實例對象來調用靜態方法//結果還是一樣的。}};t2.start();} }結果:不會互斥,鎖對象不同,一個是對實例對象加鎖,一個對類加鎖,這里直接調用Car類Car.staticRuning2(Thread.currentThread()) 其實跟調用car對象 car.staticRuning2(Thread.currentThread()) 效果一樣,因為靜態方法不屬于某個實例,而屬于類本身。
總結
以上是生活随笔為你收集整理的synchronized修饰静态方法与实例方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java二维数组排序(按照某一列值大小)
- 下一篇: ThreadLocal两个简单示例