成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試突擊:Synchronized有幾種用法?

開(kāi)發(fā) 前端
當(dāng) synchronized 修飾靜態(tài)方法時(shí),其作用范圍是整個(gè)程序,這個(gè)鎖對(duì)于所有調(diào)用這個(gè)鎖的對(duì)象都是互斥的。

在 Java 語(yǔ)言中,保證線程安全性的主要手段是加鎖,而 Java 中的鎖主要有兩種:synchronized 和 Lock,我們今天重點(diǎn)來(lái)看一下 synchronized 的幾種用法。

用法簡(jiǎn)介

使用 synchronized 無(wú)需手動(dòng)執(zhí)行加鎖和釋放鎖的操作,我們只需要聲明 synchronized 關(guān)鍵字就可以了,JVM 層面會(huì)幫我們自動(dòng)的進(jìn)行加鎖和釋放鎖的操作。synchronized 可用于修飾普通方法、靜態(tài)方法和代碼塊,接下來(lái)我們分別來(lái)看。

1.修飾普通方法

synchronized 修飾普通方法的用法如下:

/**
* synchronized 修飾普通方法
*/
public synchronized void method() {
// ....
}

當(dāng) synchronized 修飾普通方法時(shí),被修飾的方法被稱(chēng)為同步方法,其作用范圍是整個(gè)方法,作用的對(duì)象是調(diào)用這個(gè)方法的對(duì)象。

2.修飾靜態(tài)方法

synchronized 修飾靜態(tài)方法和修飾普通方法類(lèi)似,它的用法如下:

/**
* synchronized 修飾靜態(tài)方法
*/
public static synchronized void staticMethod() {
// .......
}

當(dāng) synchronized 修飾靜態(tài)方法時(shí),其作用范圍是整個(gè)程序,這個(gè)鎖對(duì)于所有調(diào)用這個(gè)鎖的對(duì)象都是互斥的。

所謂的互斥,指的是同一時(shí)間只能有一個(gè)線程能使用,其他線程只能排隊(duì)等待。

修飾普通方法 VS 修飾靜態(tài)方法

synchronized 修飾普通方法和靜態(tài)方法看似相同,但二者完全不同,對(duì)于靜態(tài)方法來(lái)說(shuō) synchronized 加鎖是全局的,也就是整個(gè)程序運(yùn)行期間,所有調(diào)用這個(gè)靜態(tài)方法的對(duì)象都是互斥的,而普通方法是針對(duì)對(duì)象級(jí)別的,不同的對(duì)象對(duì)應(yīng)著不同的鎖,比如以下代碼,同樣是調(diào)用兩次方法,但鎖的獲取完全不同,實(shí)現(xiàn)代碼如下:

import java.time.LocalDateTime;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class SynchronizedUsage {
public static void main(String[] args) throws InterruptedException {
// 創(chuàng)建線程池同時(shí)執(zhí)行任務(wù)
ExecutorService threadPool = Executors.newFixedThreadPool(10);

// 執(zhí)行兩次靜態(tài)方法
threadPool.execute(() -> {
staticMethod();
});
threadPool.execute(() -> {
staticMethod();
});

// 執(zhí)行兩次普通方法
threadPool.execute(() -> {
SynchronizedUsage usage = new SynchronizedUsage();
usage.method();
});
threadPool.execute(() -> {
SynchronizedUsage usage2 = new SynchronizedUsage();
usage2.method();
});
}

/**
* synchronized 修飾普通方法
* 本方法的執(zhí)行需要 3s(因?yàn)橛?3s 的休眠時(shí)間)
*/
public synchronized void method() {
System.out.println("普通方法執(zhí)行時(shí)間:" + LocalDateTime.now());
try {
// 休眠 3s
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

/**
* synchronized 修飾靜態(tài)方法
* 本方法的執(zhí)行需要 3s(因?yàn)橛?3s 的休眠時(shí)間)
*/
public static synchronized void staticMethod() {
System.out.println("靜態(tài)方法執(zhí)行時(shí)間:" + LocalDateTime.now());
try {
// 休眠 3s
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

以上程序的執(zhí)行結(jié)果如下:

從上述結(jié)果可以看出,靜態(tài)方法加鎖是全局的,針對(duì)的是所有調(diào)用者;而普通方法加鎖是對(duì)象級(jí)別的,不同的對(duì)象擁有的鎖也不同。

3.修飾代碼塊

我們?cè)谌粘i_(kāi)發(fā)中,最常用的是給代碼塊加鎖,而不是給方法加鎖,因?yàn)榻o方法加鎖,相當(dāng)于給整個(gè)方法全部加鎖,這樣的話鎖的粒度就太大了,程序的執(zhí)行性能就會(huì)受到影響,所以通常情況下,我們會(huì)使用 synchronized 給代碼塊加鎖,它的實(shí)現(xiàn)語(yǔ)法如下:

public void classMethod() throws InterruptedException {
// 前置代碼...

// 加鎖代碼
synchronized (SynchronizedUsage.class) {
// ......
}

// 后置代碼...
}

從上述代碼我們可以看出,相比于修飾方法,修飾代碼塊需要自己手動(dòng)指定加鎖對(duì)象,加鎖的對(duì)象通常使用 this 或 xxx.class 這樣的形式來(lái)表示,比如以下代碼:

// 加鎖某個(gè)類(lèi)
synchronized (SynchronizedUsage.class) {
// ......
}

// 加鎖當(dāng)前類(lèi)對(duì)象
synchronized (this) {
// ......
}

this VS class

使用 synchronized 加鎖 this 和 xxx.class 是完全不同的,當(dāng)加鎖 this 時(shí),表示用當(dāng)前的對(duì)象進(jìn)行加鎖,每個(gè)對(duì)象都對(duì)應(yīng)了一把鎖;而當(dāng)使用 xxx.class 加鎖時(shí),表示使用某個(gè)類(lèi)(而非類(lèi)實(shí)例)來(lái)加鎖,它是應(yīng)用程序級(jí)別的,是全局生效的,如以下代碼所示:

import java.time.LocalDateTime;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class SynchronizedUsageBlock {
public static void main(String[] args) throws InterruptedException {
// 創(chuàng)建線程池同時(shí)執(zhí)行任務(wù)
ExecutorService threadPool = Executors.newFixedThreadPool(10);

// 執(zhí)行兩次 synchronized(this)
threadPool.execute(() -> {
SynchronizedUsageBlock usage = new SynchronizedUsageBlock();
usage.thisMethod();
});
threadPool.execute(() -> {
SynchronizedUsageBlock usage2 = new SynchronizedUsageBlock();
usage2.thisMethod();
});

// 執(zhí)行兩次 synchronized(xxx.class)
threadPool.execute(() -> {
SynchronizedUsageBlock usage3 = new SynchronizedUsageBlock();
usage3.classMethod();
});
threadPool.execute(() -> {
SynchronizedUsageBlock usage4 = new SynchronizedUsageBlock();
usage4.classMethod();
});
}

/**
* synchronized(this) 加鎖
* 本方法的執(zhí)行需要 3s(因?yàn)橛?3s 的休眠時(shí)間)
*/
public void thisMethod() {
synchronized (this) {
System.out.println("synchronized(this) 加鎖:" + LocalDateTime.now());
try {
// 休眠 3s
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

/**
* synchronized(xxx.class) 加鎖
* 本方法的執(zhí)行需要 3s(因?yàn)橛?3s 的休眠時(shí)間)
*/
public void classMethod() {
synchronized (SynchronizedUsageBlock.class) {
System.out.println("synchronized(xxx.class) 加鎖:" + LocalDateTime.now());
try {
// 休眠 3s
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

以上程序的執(zhí)行結(jié)果如下:

總結(jié)

synchronized 用 3 種用法,用它可以來(lái)修飾普通方法、靜態(tài)方法和代碼塊,其中最常用的是修飾代碼塊,而修飾代碼塊時(shí)需要指定一個(gè)加鎖對(duì)象,這個(gè)加鎖對(duì)象通常使用 this 或 xxx.class 來(lái)表示,當(dāng)使用 this 時(shí),表示使用當(dāng)前對(duì)象來(lái)加鎖,而使用 class 時(shí),表示表示使用某個(gè)類(lèi)(非類(lèi)對(duì)象實(shí)例)來(lái)加鎖,它是全局生效的。

責(zé)任編輯:武曉燕 來(lái)源: Java面試真題解析
相關(guān)推薦

2022-04-24 07:59:53

synchronizJVMAPI

2022-05-23 07:35:15

單例模式懶漢模式靜態(tài)內(nèi)部類(lèi)

2022-09-19 06:16:23

事務(wù)隔離級(jí)別Spring

2022-04-18 07:36:37

TimeUnit線程休眠

2022-04-13 14:43:05

JVM同步鎖Monitor 監(jiān)視

2022-08-17 07:06:14

SpringBoot配置@Value

2022-03-07 07:33:16

線程池Java語(yǔ)言

2022-08-24 07:06:36

SpringSetter項(xiàng)目

2022-05-05 07:38:32

volatilJava并發(fā)

2022-06-06 07:35:26

MySQLInnoDBMyISAM

2024-09-27 08:57:36

2022-05-11 07:41:55

死鎖運(yùn)算線程

2022-08-22 07:06:32

MyBatisSQL占位符

2022-06-29 08:16:55

對(duì)象String字面量

2022-08-31 07:04:50

Bean作用域

2022-08-03 07:04:56

GETHTTPPOST

2022-04-26 08:02:00

locktryLocklockInterr

2022-08-10 07:06:57

IoCDISpring

2022-02-08 07:02:32

進(jìn)程線程操作系統(tǒng)

2022-08-15 07:06:50

Propertiesyml配置
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 一级黄色片在线免费观看 | 国产精品久久久久久亚洲调教 | 精品国产一区二区三区久久久蜜月 | 狠狠亚洲| 久久99久久| 国产三级日本三级 | 色婷婷精品 | 国产91中文| av性色 | 国产高潮av | 亚洲欧美高清 | 国产精品久久久久久久久久尿 | 欧美一区日韩一区 | 国产婷婷综合 | 欧美黄色性生活视频 | 成在线人视频免费视频 | 日韩欧美一区二区三区免费观看 | 中文字幕一区二区三区四区 | 国产一区二区三区久久久久久久久 | 黄色成人免费看 | 日韩一区二区三区视频 | 久久99久久 | www.日本精品 | 国产色黄 | 综合久久综合久久 | 中文字幕亚洲一区二区三区 | 97精品国产 | 亚洲精品久久久久久国产精华液 | 自拍偷拍av | 自拍第一页 | 欧美成人免费 | 成人午夜免费福利视频 | 亚洲精品一| 成人亚洲一区 | 国产成人一区二区 | 欧美成人精品 | 欧美一区视频在线 | 91成人在线 | 日韩一区二区在线播放 | 91在线免费视频 | 国产一区二区三区精品久久久 |