java併發-java同步塊(8)
阿新 • • 發佈:2019-01-25
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;
}
}