synchronized 作用在普通方法與靜態方法的區別


synchronized是Java中的關鍵字,是一種同步鎖。它修飾的對象有以下幾種:
1. 修飾一個代碼塊,被修飾的代碼塊稱為同步語句塊,其作用的范圍是大括號{}括起來的代碼,作用的對象是調用這個代碼塊的對象;
2. 修飾一個方法,被修飾的方法稱為同步方法,其作用的范圍是整個方法,作用的對象是調用這個方法的對象;
3. 修改一個靜態的方法,其作用的范圍是整個靜態方法,作用的對象是這個類的所有對象;
4. 修改一個類,其作用的范圍是synchronized后面括號括起來的部分,作用主的對象是這個類的所有對象。

package com.fyb.concurrent;

public class SynchronizedTest {
	
	private int num;
	
	public synchronized void method01(String arg) {
		try {
			if("a".equals(arg)){
				num = 100;
				System.out.println("tag a set number over");
				Thread.sleep(1000);
			}else{
				num = 200;
				System.out.println("tag b set number over");
			}
			
			System.out.println("tag = "+ arg + ";num ="+ num);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		final SynchronizedTest m1 = new SynchronizedTest();
		final SynchronizedTest m2 = new SynchronizedTest();
		
		Thread t1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				m1.method01("a");
			}
		});
		t1.start();
		
		Thread t2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				m2.method01("b");
			}
		});
		t2.start();
		
	}
}

執行輸出:

tag a set number over
tag b set number over
tag = b;num =200
tag = a;num =100

可以看出,兩個不同的對象m1和m2的method01()方法執行並沒有互斥,因為這里synchronized是分別持有兩個對象的鎖。如果要想m1,m2兩個對象競爭同一個鎖,則需要在method01()上加上static修飾。如下:

package com.fyb.concurrent;

public class SynchronizedTest {
	
	private static int  num;
	
	public static synchronized void method01(String arg) {
		try {
			if("a".equals(arg)){
				num = 100;
				System.out.println("tag a set number over");
				Thread.sleep(1000);
			}else{
				num = 200;
				System.out.println("tag b set number over");
			}
			
			System.out.println("tag = "+ arg + ";num ="+ num);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		final SynchronizedTest m1 = new SynchronizedTest();
		final SynchronizedTest m2 = new SynchronizedTest();
		
		Thread t1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				m1.method01("a");
			}
		});
		t1.start();
		
		Thread t2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				m2.method01("b");
			}
		});
		t2.start();
		
	}
}

輸出結果:

tag a set number over
tag = a;num =100
tag b set number over
tag = b;num =200

小結:

synchronized修飾不加static的方法,鎖是加在單個對象上,不同的對象沒有競爭關系;修飾加了static的方法,鎖是加載類上,這個類所有的對象競爭一把鎖。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM