亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺析Java 并發(fā)編程中的synchronized

 更新時間:2020年12月03日 09:00:04   作者:拾階求上  
這篇文章主要介紹了Java 并發(fā)編程中的synchronized的相關(guān)資料,幫助大家更好的理解和學習Java并發(fā)編程,感興趣的朋友可以了解下

synchronized關(guān)鍵字,我們一般稱之為“同步鎖”,用它來修飾需要同步的方法和需要同步代碼塊,默認是當前對象作為鎖的對象。在用synchronized修飾類時(或者修飾靜態(tài)方法),默認是當前類的Class對象作為鎖的對象,故存在著方法鎖、對象鎖、類鎖這樣的概念。

一、沒有設置線程同步的情況

先給出以下代碼感受下代碼執(zhí)行的時候為什么需要同步?代碼可能比較枯燥,配上業(yè)務理解起來就會舒服很多,學生軍訓,有三列,每列5人,需要報數(shù),每個線程負責每一列報數(shù)。

class SynchronizedExample {
	protected static int num = 0;
	protected void numberOff() {
		for(int i=0; i<5; i++) {
			num++;
System.out.println(Thread.currentThread().getName()+":"+SynchronizedExample.num);
		}
	}
}

public class SynchronizedTest {
	public static void main(String[] args) throws InterruptedException {
		SynchronizedExample se = new SynchronizedExample();
		for(int i=1; i<=3; i++) {
			new Thread( ()-> {se.numberOff();}, "線程"+i).start();
		}
	}
}

執(zhí)行結(jié)果如下:

線程1:1
線程2:2
線程1:3
線程3:4
.......

之所以出現(xiàn)這種情況,是因為三個線程是異步的,沒有同步。
對應的業(yè)務場景就是,在第一列沒有完成報數(shù)的時候,其他隊列搶報了,這在現(xiàn)實中是不允許的,所以需要類似于synchronized等具有同步功能的關(guān)鍵字粉末登場。

二、方法同步鎖

當報數(shù)方法加上synchronized關(guān)鍵字之后,就會一列一列的報數(shù)。

protected synchronized void numberOff() {
	for(int i=0; i<5; i++) {
		num++;
System.out.println(Thread.currentThread().getName()+":"+SynchronizedExample.num);
	}
}

執(zhí)行結(jié)果如下:

線程1:1
線程1:2
線程1:3
線程1:4
......

寫到這里還是要從技術(shù)層面講下原理,當一個線程執(zhí)行帶有synchronized關(guān)鍵字的方法時,該線程會在該方法處設置一個鎖(其他線程打不開這個鎖,只能在外邊等該線程釋放掉該鎖,一般都是執(zhí)行完所有代碼后主動釋放鎖),表示此方法是當前線程獨占的,對應到上述業(yè)務中就是一次只能有一個隊列報數(shù)。

三、對象鎖

改進后的代碼用到了一個對象鎖,該對象鎖默認是當前對象,上述代碼等同于以下代碼:

protected void numberOff() {
	synchronized (this) {
		for (int i = 0; i < 5; i++) {
			num++;
			System.out.println(Thread.currentThread().getName() + ":" + SynchronizedExample.num);
		}
	}
}

當多個線程用一個對象鎖,各個線程可以達到同步的作用,如果每個線程都用自己的對象鎖,那么synchronized就失去了同步的作用。如以下代碼:

class SynchronizedExample {
	protected static int num = 0;
	protected void numberOff() {
		synchronized (this) {
			for (int i = 0; i < 5; i++) {
				num++;
			System.out.println(Thread.currentThread().getName() + ":" + SynchronizedExample.num);
			}
		}
	}
}
public class SynchronizedTest {
	public static void main(String[] args) throws InterruptedException {
		SynchronizedExample se = new SynchronizedExample();
		for(int i=1; i<=3; i++) {
			new Thread( ()-> {new SynchronizedExample().numberOff();}, "隊列"+i).start();
		}
	}
}

執(zhí)行結(jié)果如下:

線程1:1
線程2:2
線程1:3
線程3:4
.......

有讀者會說不同線程執(zhí)行的是不同對象中的方法,肯定達不到同步的效果,也對,也很有道理,接著看如下代碼:

class SynchronizedExample {
	protected static int num = 0;
	protected void numberOff(Object lock) {
		synchronized (lock) {
			for (int i = 0; i < 5; i++) {
				num++;
			System.out.println(Thread.currentThread().getName() + ":" + SynchronizedExample.num);
			}
		}
	}
}

public class SynchronizedTest {
	public static void main(String[] args) throws InterruptedException {
		SynchronizedExample se = new SynchronizedExample();
		for(int i=1; i<=3; i++) {
			new Thread( ()-> {se.numberOff(new Object());}, "隊列"+i).start();
		}
	}
}

執(zhí)行結(jié)果如下:

線程1:1
線程2:2
線程1:3
線程3:4
.......

四、類鎖

對于上述問題,讀者應該得出一個結(jié)論,要想達到同步的效果,必須用同一個鎖,此時類鎖可以粉末登場。看如下代碼:

protected void numberOff(Object lock) {
	synchronized (SynchronizedExample.class) {
		for (int i = 0; i < 5; i++) {
			num++;
			System.out.println(Thread.currentThread().getName() + ":" + SynchronizedExample.num);
		}
	}
}

上述代碼可以達到同步的效果。

五、靜態(tài)鎖

靜態(tài)鎖是針對靜態(tài)方法而言,當一個靜態(tài)方法中有synchronized關(guān)鍵字時,默認的是使用當前類字節(jié)碼對象作為鎖。代碼示例如下:

class SynchronizedExample {
	protected static int num = 0;
	protected synchronized static void numberOff() {
		for (int i = 0; i < 5; i++) {
			num++;
			System.out.println(Thread.currentThread().getName() + ":" + SynchronizedExample.num);
		}
	}
}

public class SynchronizedTest {
	public static void main(String[] args) throws InterruptedException {
		for (int i = 1; i <= 3; i++) {
			new Thread(() -> { new SynchronizedExample().numberOff(); }, "隊列" + i).start();
		}
	}
}

六、線程池實現(xiàn)

最后用線程池將上述代碼寫一下

package ioo;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class SynchronizedExample {
	protected static int num = 0;
	protected synchronized static void numberOff() {
		for (int i = 0; i < 5; i++) {
			num++;
			System.out.println(Thread.currentThread().getName() + ":" + SynchronizedExample.num);
		}
	}
}

public class SynchronizedTest {
	public static void main(String[] args) throws InterruptedException {
		ExecutorService executorService = Executors.newCachedThreadPool();
		for(int i=1; i<=3; i++) {
			executorService.execute(() -> new SynchronizedExample().numberOff());
		}
	}
}

以上就是淺析Java 并發(fā)編程中的synchronized的詳細內(nèi)容,更多關(guān)于Java 并發(fā)編程 synchronized的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java實現(xiàn)簡單的五子棋游戲

    java實現(xiàn)簡單的五子棋游戲

    這篇文章主要為大家詳細介紹了java實現(xiàn)簡單的五子棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Spring輕松解決循環(huán)依賴

    Spring輕松解決循環(huán)依賴

    Spring的解決循環(huán)依賴是有前置條件的,要解決循環(huán)依賴我們首先要了解Spring Bean對象的創(chuàng)建過程和依賴注入的方式。依賴注入方式,我之前的博客有所分享,大家可以在看本篇文章之前進行一下小小的回顧
    2023-04-04
  • spring動態(tài)注冊bean?AOP失效原理解析

    spring動態(tài)注冊bean?AOP失效原理解析

    這篇文章主要為大家介紹了spring動態(tài)注冊bean使AOP失效原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • logback 配置詳解(推薦)

    logback 配置詳解(推薦)

    這篇文章主要介紹了logback 配置詳解(推薦),詳細的介紹了logback的組成使用和配置,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • java HashMap通過value反查key的代碼示例

    java HashMap通過value反查key的代碼示例

    本文講解了java HashMap通過value反查key的方法,直接提供代碼供大家參考使用
    2013-11-11
  • SpringBoot集成MyBatis的三種方式

    SpringBoot集成MyBatis的三種方式

    Spring Boot與MyBatis的集成為Java開發(fā)者提供了一種簡便而強大的方式來訪問和操作數(shù)據(jù)庫,在本文中,我們將深入解析Spring Boot集成MyBatis的多種方式,文中有詳細的代碼示例供大家參考,需要的朋友可以參考下
    2023-12-12
  • 如何在spring boot中進行參數(shù)校驗示例詳解

    如何在spring boot中進行參數(shù)校驗示例詳解

    這篇文章主要介紹了如何在spring-boot中進行參數(shù)校驗及l(fā)ombok的使用詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • Java中==符號與equals()的使用詳解(測試兩個變量是否相等)

    Java中==符號與equals()的使用詳解(測試兩個變量是否相等)

    下面小編就為大家?guī)硪黄狫ava中==符號與equals()的使用詳解(測試兩個變量是否相等)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • Java集合之Disruptor操作示例

    Java集合之Disruptor操作示例

    這篇文章主要為大家介紹了Java集合之Disruptor操作示例介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • 選擇java的理由:java之父訪談實錄

    選擇java的理由:java之父訪談實錄

    選擇java的理由:java之父訪談實錄...
    2006-12-12

最新評論