1. 程式人生 > >java併發-java同步塊(8)

java併發-java同步塊(8)

java同步塊也就是讓同步塊的程式碼只能同時有一個執行緒在執行,並且可以保證原子性和可見性。通過synchronized或者lock實現。

物件方法同步

package com.concurenny.chapter.seven;

/**
 * 建立者:Mr lebron 建立時間:2017年11月17日 下午3:05:20
 */
public class ObjectMethodSynchronized {
	public static void main(String[] args) {
		final ObjectMethodSynchronized obj1 = new ObjectMethodSynchronized();
		final ObjectMethodSynchronized obj2 = new ObjectMethodSynchronized();
		Thread A = new Thread(()->{
			obj1.add(1);
		});
		Thread B = new Thread(()->{
			obj1.add(1);
		});
		Thread C = new Thread(()->{
			obj2.add(1);
		});
		Thread D = new Thread(()->{
			obj2.add(1);
		});
		A.start();
		B.start();
		C.start();
		D.start();
	}

	private int count = 0;

	/**
	 * 該物件的這個方法只能由一個執行緒同時執行。多個物件可以有多個執行緒執行。 因為synchronized持有的是當前物件的鎖。
	 * 例如:ObjectMethodSynchronized obj1,ObjectMethodSynchronized obj2;執行緒A,B,C,D.
	 * A執行obj1.add(1),B執行obj1.add(1),C執行obj2.add(1),D執行obj2.add(1)
	 * 可能的情況:A獲得obj1的鎖,執行add,B發現鎖obj1已經被拿了,阻塞進入等待佇列。
	 * C獲得obj2的鎖,執行add,D發現鎖obj2已經被拿了,阻塞進入等待佇列。
	 * 此時就有兩個執行緒在執行
	 */
	public synchronized int add(int plus) {
		 System.out.println(count += plus);
		 try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		 return count;
	}
}

靜態方法同步
package com.concurenny.chapter.seven;

/**
 * 建立者:Mr lebron 建立時間:2017年11月17日 下午3:05:20
 */
public class StaticMethodSynchronized {
	public static void main(String[] args) {
		final StaticMethodSynchronized obj1 = new StaticMethodSynchronized();
		final StaticMethodSynchronized obj2 = new StaticMethodSynchronized();
		Thread A = new Thread(()->{
			obj1.add(1);
		});
		Thread B = new Thread(()->{
			obj1.add(1);
		});
		Thread C = new Thread(()->{
			obj2.add(1);
		});
		Thread D = new Thread(()->{
			obj2.add(1);
		});
		A.start();
		B.start();
		C.start();
		D.start();
	}

	private static int count = 0;

	/**
	 * 這個方法只能由一個執行緒同時執行。 因為synchronized持有的是StaticMethodSynchronized這個類物件的鎖,這個類物件只可能有一個
	 * 例如:ObjectMethodSynchronized obj1,ObjectMethodSynchronized obj2;執行緒A,B,C,D.
	 * A執行obj1.add(1),B執行obj1.add(1),C執行obj2.add(1),D執行obj2.add(1)
	 * 可能的情況:A獲得類物件(ObjectMethodSynchronized)的鎖,執行add,B發現鎖類物件(ObjectMethodSynchronized)已經被拿了,阻塞進入等待佇列。
	 * D發現鎖類物件(ObjectMethodSynchronized)已經被拿了,阻塞進入等待佇列,D發現鎖類物件(ObjectMethodSynchronized)已經被拿了,阻塞進入等待佇列。
	 * 此時只可能有一個執行緒在執行
	 */
	public synchronized static int add(int plus) {
		 System.out.println(count += plus);
		 try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		 return count;
	}
}
物件方法同步塊
package com.concurenny.chapter.seven;

/**
 * 建立者:Mr lebron 建立時間:2017年11月17日 下午3:05:20
 */
public class ObjectMethodSynchronizedBlock {
	public static void main(String[] args) {
		final ObjectMethodSynchronizedBlock obj1 = new ObjectMethodSynchronizedBlock();
		final ObjectMethodSynchronizedBlock obj2 = new ObjectMethodSynchronizedBlock();
		Thread A = new Thread(()->{
			obj1.add(1);
		});
		Thread B = new Thread(()->{
			obj1.add(1);
		});
		Thread C = new Thread(()->{
			obj2.add(1);
		});
		Thread D = new Thread(()->{
			obj2.add(1);
		});
		A.start();
		B.start();
		C.start();
		D.start();
	}

	private int count = 0;

	/**
	 * 該物件的這個方法只能由一個執行緒同時執行。多個物件可以有多個執行緒執行。 因為synchronized持有的是當前物件的鎖。
	 * 例如:ObjectMethodSynchronized obj1,ObjectMethodSynchronized obj2;執行緒A,B,C,D.
	 * A執行obj1.add(1),B執行obj1.add(1),C執行obj2.add(1),D執行obj2.add(1)
	 * 可能的情況:A獲得obj1的鎖,執行add,B發現鎖obj1已經被拿了,阻塞進入等待佇列。
	 * C獲得obj2的鎖,執行add,D發現鎖obj2已經被拿了,阻塞進入等待佇列。
	 * 此時就有兩個執行緒在執行
	 */
	public  int add(int plus) {
		//這種方式的鎖和方法同步的鎖一樣,都是該方法所屬物件,只是可能在同步塊的上方後者下面會有其他程式碼
		System.out.println("進入同步塊前:");
		 synchronized (this) {
			System.out.println(count += plus);
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		 System.out.println("退出同步塊後:");
	 return count;
	}
}

靜態方法同步塊
package com.concurenny.chapter.seven;

/**
 * 建立者:Mr lebron 建立時間:2017年11月17日 下午3:05:20
 */
public class StaticMethodSynchronizedBlock {
	public static void main(String[] args) {
		final StaticMethodSynchronizedBlock obj1 = new StaticMethodSynchronizedBlock();
		final StaticMethodSynchronizedBlock obj2 = new StaticMethodSynchronizedBlock();
		Thread A = new Thread(()->{
			obj1.add(1);
		});
		Thread B = new Thread(()->{
			obj1.add(1);
		});
		Thread C = new Thread(()->{
			obj2.add(1);
		});
		Thread D = new Thread(()->{
			obj2.add(1);
		});
		A.start();
		B.start();
		C.start();
		D.start();
	}

	private static int count = 0;

	/**
	*原理同對象方法同步塊
	 */
	public static  int add(int plus) {
		//這種方式的鎖和方法同步的鎖一樣,都是該StaticMethodSynchronizedBlock類物件
		System.out.println("進入同步塊前:");
		 synchronized (StaticMethodSynchronizedBlock.class) {
			System.out.println(count += plus);
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		 System.out.println("退出同步塊後:");
	 return count;
	}
}