国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

cmp830871的個人空間 http://www.qingdxww.cn/space-uid-170937.html [收藏] [復制] [RSS]

博客

java并發中的Synchronized關鍵詞

已有 682 次閱讀2022-11-30 04:50

java并發中的Synchronized關鍵詞

如果在多線程的環境中,我們經常會遇到資源競爭的情況,比如多個線程要去同時修改同一個共享變量,這時候,就需要對資源的訪問方法進行一定的處理,保證同一時間只有一個線程訪問。

java提供了synchronized關鍵字,方便我們實現上述操作。

為什么要同步
我們舉個例子,我們創建一個類,提供了一個setSum的方法:

public class SynchronizedMethods {

    private int sum = 0;

    public void calculate() {
        setSum(getSum() + 1);
    }
}
1.
2.
3.
4.
5.
6.
7.
8.
如果我們在多線程的環境中調用這個calculate方法:

@Test
    public void givenMultiThread_whenNonSyncMethod() throws InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool(3);
        SynchronizedMethods summation = new SynchronizedMethods();

        IntStream.range(0, 1000)
                .forEach(count -> service.submit(summation::calculate));
        service.shutdown();
        service.awaitTermination(1000, TimeUnit.MILLISECONDS);

        assertEquals(1000, summation.getSum());
    }
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
按照上面的方法,我們預計要返回1000, 但是實際上基本不可能得到1000這個值,因為在多線程環境中,對同一個資源進行同時操作帶來的不利影響。

那我們怎么才能夠建線程安全的環境呢?

Synchronized關鍵詞
java提供了多種線程安全的方法,本文主要講解Synchronized關鍵詞,Synchronized關鍵詞可以有很多種形式:

Instance methods
Static methods
Code blocks
當我們使用synchronized時,java會在相應的對象上加鎖,從而在同一個對象等待鎖的方法都必須順序執行,從而保證了線程的安全。

Synchronized Instance Methods
Synchronized關鍵詞可以放在實例方法的前面:

public synchronized void synchronisedCalculate() {
        setSum(getSum() + 1);
    }
1.
2.
3.
看下調用結果:

@Test
public void givenMultiThread_whenMethodSync() {
    ExecutorService service = Executors.newFixedThreadPool(3);
    SynchronizedMethods method = new SynchronizedMethods();
 
    IntStream.range(0, 1000)
      .forEach(count -> service.submit(method::synchronisedCalculate));
    service.awaitTermination(1000, TimeUnit.MILLISECONDS);
 
    assertEquals(1000, method.getSum());
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
這里synchronized將會鎖住該方法的實例對象,多個線程中只有獲得該實例對象鎖的線程才能夠執行。

Synchronized Static Methods
Synchronized關鍵詞也可以用在static方法前面:

public static synchronized void syncStaticCalculate() {
        staticSum = staticSum + 1;
    }
1.
2.
3.
Synchronized放在static方法前面和實例方法前面鎖住的對象不同。放在static方法前面鎖住的對象是這個Class本身,因為一個Class在JVM中只會存在一個,所以不管有多少該Class的實例,在同一時刻只會有一個線程可以執行該放方法。

@Test
    public void givenMultiThread_whenStaticSyncMethod() throws InterruptedException {
        ExecutorService service = Executors.newCachedThreadPool();

        IntStream.range(0, 1000)
                .forEach(count ->
                        service.submit(SynchronizedMethods::syncStaticCalculate));
        service.shutdown();
        service.awaitTermination(100, TimeUnit.MILLISECONDS);

        assertEquals(1000, SynchronizedMethods.staticSum);
    }
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Synchronized Blocks
有時候,我們可能不需要Synchronize整個方法,而是同步其中的一部分,這時候,我們可以使用Synchronized Blocks:

public void performSynchronizedTask() {
        synchronized (this) {
            setSum(getSum() + 1);
        }
    }
1.
2.
3.
4.
5.
我們看下怎么測試:

@Test
    public void givenMultiThread_whenBlockSync() throws InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool(3);
        SynchronizedMethods synchronizedBlocks = new SynchronizedMethods();

        IntStream.range(0, 1000)
                .forEach(count ->
                        service.submit(synchronizedBlocks::performSynchronizedTask));
        service.shutdown();
        service.awaitTermination(100, TimeUnit.MILLISECONDS);

        assertEquals(1000, synchronizedBlocks.getSum());
    }
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
上面我們同步的是實例,如果在靜態方法中,我們也可以同步class:

public static void performStaticSyncTask(){
        synchronized (SynchronizedMethods.class) {
            staticSum = staticSum + 1;
        }
    }
1.
2.
3.
4.
5.
我們看下怎么測試:

登錄后復制 
@Test
    public void givenMultiThread_whenStaticSyncBlock() throws InterruptedException {
        ExecutorService service = Executors.newCachedThreadPool();

        IntStream.range(0, 1000)
                .forEach(count ->
                        service.submit(SynchronizedMethods::performStaticSyncTask));
        service.shutdown();
        service.awaitTermination(100, TimeUnit.MILLISECONDS);

        assertEquals(1000, SynchronizedMethods.staticSum);
    }


路過

雞蛋

鮮花

握手

雷人

評論 (0 個評論)

facelist

您需要登錄后才可以評論 登錄 | 立即注冊

關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
返回頂部
主站蜘蛛池模板: 91久久青青草原线免费 | 欧美在线观看一区二区三区 | 日日干综合 | 亚洲一区二区三区在线免费观看 | 久久91精品国产一区二区 | 天堂动漫| 女男羞羞视频网站免费 | 含羞草app | 成人羞羞视频在线看网址 | 日本高清在线视频www色下载 | 91小视频app 91香蕉在线看私人影院 | 日韩成人毛片高清视频免费看 | 4438x全国最大成人网 | 国产精品免费福利 | 国产成人aa免费视频 | 四虎影视在线看免费 720p | 欧美极品在线视频 | 亚洲欧美第一 | 国产精品七七在线播放 | 91成人免费福利网站在线 | 欧美色青 | 四虎在线播放免费永久视频 | 伊人导航 | 97免费看| 日本不卡在线视频高清免费 | 黄色在线视频播放 | 亚洲欧洲日产v特级毛片 | 99爱视频免费高清在线观看 | 中国一级毛片aaa片 中国性天美传媒 | 亚洲成年网站在线观看 | 晚上看的www视频高清免费动漫 | 欧洲不卡一卡2卡三卡4卡网站 | 日韩网站在线 | 欧美高清第一页 | 热久久最新 | 国产精品嘿咻嘿咻在线播放 | 91亚洲精品国产自在现线 | 免费国产成高清人在线视频 | 成在线人永久免费视频下载 | 日韩色吧 | 美女视频永久黄网站免费观看国产 |