理解synchronized

1.synchronized這個是同步標識,打上這個標識能夠理解爲在這個地方上加了一把鎖
2.synchronized能夠分爲:對象鎖,區域鎖,和方法鎖
3.當一個方法或區域被鎖住時,那麼其標識爲synchronized的方法或區域都沒法執行,直到鎖被釋放
4.synchronized不具備繼承性,若是父類有同步標識,子類要想同步也必須加上同步標識
5.synchronized有重入的功能,例:同步方法A調用同步方法B。或子類的同步方法調用父類的同步方法
6.靜態同步 synchronized方法,是對當前*.java文件對應的Class類進行持鎖。而非靜態同步是對實例持鎖
7.鎖的粒度小,則能提升吐吞量
java

區域鎖------------------------------
this

public static class CommonObject{
		 public void printName() throws InterruptedException{
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			System.out.println("張三");
		}
		 public void printAge() throws InterruptedException{
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			System.out.println("25");
		}
		 public void printOther() throws InterruptedException{
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			System.out.println("未知");
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		final CommonObject commonObject = new CommonObject();
		
		new Thread("printName"){
			public void run() {
				try {
					synchronized(commonObject){
						commonObject.printName();
					}
				} catch (InterruptedException e) {
				}
			};
		}.start();
		
		new Thread("printAge"){
			public void run() {
				try {
					synchronized(commonObject){
						commonObject.printAge();
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			};
		}.start();
		
		new Thread("printOther"){
			public void run() {
				try {
					synchronized(commonObject){
						commonObject.printOther();
					}
				} catch (InterruptedException e) {
				}
			};
		}.start();
	}
輸出:
printName
張三
printOther
未知
printAge
25

輸出分析:三個線程同時持有了commonObject,因此在同一時刻只有一個線程能操做同步代碼,而且試圖直接調用commonObject中的synchronized方法也會被鎖住
1.在多個線程持有「對象監視器」爲同一對象的前提下,同一時間只有一個線程能夠執行synchronized同步代碼塊中的代碼,或持有對象中synchronized方法 spa

方法鎖-------------------------------
public static class CommonObject{
		synchronized public void printName() throws InterruptedException{
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			System.out.println("張三");
		}
		synchronized public void printAge() throws InterruptedException{
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			System.out.println("25");
		}
		synchronized public void printOther() throws InterruptedException{
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			System.out.println("未知");
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		final CommonObject commonObject = new CommonObject();
		
		new Thread("printName"){
			public void run() {
				try {
					commonObject.printName();
				} catch (InterruptedException e) {
				}
			};
		}.start();
		
		new Thread("printAge"){
			public void run() {
				try {
					commonObject.printAge();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			};
		}.start();
		
		new Thread("printOther"){
			public void run() {
				try {
					commonObject.printOther();
				} catch (InterruptedException e) {
				}
			};
		}.start();
	}
輸出結果:
printName
張三
printAge
25
printOther
未知

輸出分析
1.對其餘synchronized同步方法或synchronized(this)同步代碼塊調用呈阻塞狀態。
2.同一時間只有一個線程能夠執行synchronized同步方法中的代碼
線程

對象鎖----------------------------
code

public static class CommonObject { public void printName() { synchronized (this) { System.out.println(Thread.currentThread().getName()); System.out.println("張三"); } } public void printAge() { synchronized (this) { System.out.println(Thread.currentThread().getName()); System.out.println("25"); } } public void printOther() { synchronized (this) { System.out.println(Thread.currentThread().getName()); System.out.println("未知"); } } } public static void main(String[] args) throws InterruptedException { final CommonObject commonObject = new CommonObject(); new Thread("printName") { public void run() { commonObject.printName(); }; }.start(); new Thread("printAge") { public void run() { commonObject.printAge(); }; }.start(); new Thread("printOther") { public void run() { commonObject.printOther(); }; }.start(); }

輸出結果:
printName
張三
printAge
25
printOther
未知 對象

輸出分析
1.對其餘synchronized同步方法或synchronized(this)同步代碼塊調用呈阻塞狀態
2.同一時間只有一個線程能夠執行synchronized(this)同步代碼塊中的代碼

繼承

混合使用------------------------------
get

public static class CommonObject{
		synchronized public void printName() throws InterruptedException{
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			System.out.println("張三");
		}
		 public void printAge() throws InterruptedException{
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			System.out.println("25");
		}
		 public void printOther() throws InterruptedException{
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			System.out.println("未知");
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		final CommonObject commonObject = new CommonObject();
		
		new Thread("printName"){
			public void run() {
				try {
					commonObject.printName();
				} catch (InterruptedException e) {
				}
			};
		}.start();
		
		new Thread("printAge"){
			public void run() {
				try {
					synchronized(commonObject){
						commonObject.printAge();
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			};
		}.start();
		
		new Thread("printOther"){
			public void run() {
				try {
					synchronized(commonObject){
						commonObject.printOther();
					}
				} catch (InterruptedException e) {
				}
			};
		}.start();
	}
輸出:
printName
張三
printOther
未知
printAge
25

輸出分析:

1.當「printName」線程執行了printName方法,但方法是同步的,因此commonObject中全部synchronized方法都被鎖住了,同時鎖住了synchronized(this){},和synchronized(commonObject){}區中的操做。
2.當「printOther」線程啓動了並持有了commonObject對象,因此commonObject中全部的synchronized方法都被鎖住了,同時鎖住了synchronized(this){},和synchronized(commonObject){}區中的操做。
同步

靜態鎖------------------------------------------- io

public static class CommonObject{
	synchronized static public void printName() throws InterruptedException{
		System.out.println(Thread.currentThread().getName());
		Thread.sleep(1000);
		System.out.println("張三");
	}
	public void printAge() throws InterruptedException{
		synchronized(CommonObject.class){
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			System.out.println("35");
		}
	}
}

public static void main(String[] args) throws InterruptedException {
	final CommonObject commonObject = new CommonObject();
	
	new Thread("printName"){
		public void run() {
			try {
				CommonObject.printName();
			} catch (InterruptedException e) {
			}
		};
	}.start();
	
	new Thread("printAge"){
		public void run() {
			try {
				commonObject.printAge();
			} catch (InterruptedException e) {
			}
		};
	}.start();
}



輸出結果:
printName
張三
printAge
35

輸出分析
1. 靜態方法printName 加上了 synchronized 標識,鎖的對象是CommonObject.Class。同一時間CommonObject中全部靜態同步方法,及synchronized(CommonObject.Class){}區中代碼,只有一個能夠執行。
相關文章
相關標籤/搜索