最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)線程同步的四種方式總結(jié)

 更新時(shí)間:2022年09月30日 14:26:30   作者:mikechen  
Java線程同步屬于Java多線程與并發(fā)編程的核心點(diǎn),需要重點(diǎn)掌握,下面我就來(lái)詳解Java線程同步的4種主要的實(shí)現(xiàn)方式,需要的可以參考一下

什么是線程同步

當(dāng)使用多個(gè)線程來(lái)訪問(wèn)同一個(gè)數(shù)據(jù)時(shí),將會(huì)導(dǎo)致數(shù)據(jù)不準(zhǔn)確,相互之間產(chǎn)生沖突,非常容易出現(xiàn)線程安全問(wèn)題,如下圖所示:

比如多個(gè)線程都在操作同一數(shù)據(jù),都打算修改商品庫(kù)存,這樣就會(huì)導(dǎo)致數(shù)據(jù)不一致的問(wèn)題。

線程同步的真實(shí)意思,其實(shí)是“排隊(duì)”:幾個(gè)線程之間要排隊(duì),一個(gè)一個(gè)對(duì)共享資源進(jìn)行操作,而不是同時(shí)進(jìn)行操作。

所以我們用同步機(jī)制來(lái)解決這些問(wèn)題,加入同步鎖以避免在該線程沒(méi)有完成操作之前,被其他線程的調(diào)用,從而保證了該變量的唯一性和準(zhǔn)確性。

線程同步的幾種方式

1.使用synchronized關(guān)鍵字

這種方式比較靈活,修飾一個(gè)代碼塊,被修飾的代碼塊稱為同步語(yǔ)句塊。

其作用的范圍是大括號(hào){}括起來(lái)的代碼,作用的對(duì)象是調(diào)用這個(gè)代碼塊的對(duì)象,如下格式:

synchronized(對(duì)象) {					//得到對(duì)象的鎖,才能操作同步代碼

    需要被同步代碼;

}

通常沒(méi)有必要同步整個(gè)方法,使用synchronized代碼塊同步關(guān)鍵代碼即可。

具體的示例如下:

public class SynchronizedThread {

    class Bank {

        private int account = 200;

        public int getAccount() {

            return account;

        }

        /**
         * 用同步方法實(shí)現(xiàn)
         *
         * @param money
         */

        public synchronized void save(int money) {
            account += money;

        }

        /**
         * 用同步代碼塊實(shí)現(xiàn)
         *
         * @param money
         */

        public void save1(int money) {
            synchronized (this) {

                account += money;
           }

        }
    }


    class NewThread implements Runnable {
        private Bank bank;

        public NewThread(Bank bank) {

            this.bank = bank;

        }


        @Override
        public void run() {

            for (int i = 0; i < 10; i++) {
                // bank.save1(10);
                bank.save(10);
                System.out.println(i + "賬戶余額為:" + bank.getAccount());

            }

        }

    }


    /**
     * 建立線程,調(diào)用內(nèi)部類
     */

    public void useThread() {
        Bank bank = new Bank();
        NewThread new_thread = new NewThread(bank);
        System.out.println("線程1");

        Thread thread1 = new Thread(new_thread);
        thread1.start();
        System.out.println("線程2");
        Thread thread2 = new Thread(new_thread);
        thread2.start();

    }

    public static void main(String[] args) {

        SynchronizedThread st = new SynchronizedThread();

        st.useThread();

    }
}

如果你還想深入了解Synchronized的底層原理,可以看 Synchronized的實(shí)現(xiàn)原理詳解(看這篇就夠了)

2.使用ReentrantLock

ReentrantLock類是可重入、互斥、實(shí)現(xiàn)了Lock接口的鎖,它與使用synchronized方法具有相同的基本行為和語(yǔ)義,并且擴(kuò)展了其能力。

 

private int account = 100;

            //需要聲明這個(gè)鎖

            private Lock lock = new ReentrantLock();

            public int getAccount() {

                return account;

            }

            //這里不再需要synchronized

            public void save(int money) {

                lock.lock();

                try{

                    account += money;

                }finally{

                    lock.unlock();

                }

            }

        }

synchronized 與 Lock 的對(duì)比

ReentrantLock是顯示鎖,手動(dòng)開(kāi)啟和關(guān)閉鎖,別忘記關(guān)閉鎖;

synchronized 是隱式鎖,出了作用域自動(dòng)釋放;

ReentrantLock只有代碼塊鎖,synchronized 有代碼塊鎖和方法鎖;

使用 ReentrantLock鎖,JVM 將花費(fèi)較少的時(shí)間來(lái)調(diào)度線程,線程更好,并且具有更好的擴(kuò)展性(提供更多的子類);

優(yōu)先使用順序:

ReentrantLock> synchronized 同步代碼塊> synchronized 同步方法

3.使用原子變量實(shí)現(xiàn)線程同步

為了完成線程同步,我們將使用原子變量(Atomic***開(kāi)頭的)來(lái)實(shí)現(xiàn)。

比如典型代表:AtomicInteger類存在于java.util.concurrent.atomic中,該類表示支持原子操作的整數(shù),采用getAndIncrement方法以原子方法將當(dāng)前的值遞加。

具體示例如下:

private AtomicInteger account = new AtomicInteger(100);

        public AtomicInteger getAccount() {

            return account;

        }

        public void save(int money) {

            account.addAndGet(money);

        }

4.ThreadLocal實(shí)現(xiàn)線程同步

如果使用ThreadLocal管理變量,則每一個(gè)使用該變量的線程都獲得該變量的副本,副本之間相互獨(dú)立,這樣每一個(gè)線程都可以隨意修改自己的變量副本,而不會(huì)對(duì)其他線程產(chǎn)生影響,從而實(shí)現(xiàn)線程同步。

具體代碼示例如下:

//只改Bank類,其余代碼與上同

        public class Bank{
            // 創(chuàng)建一個(gè)線程本地變量 ThreadLocal

            private static ThreadLocal<Integer> account = new ThreadLocal<Integer>(){
                @Override

                //返回當(dāng)前線程的"初始值"

                protected Integer initialValue(){

                    return 100;

                }

            };

            public void save(int money){

                //設(shè)置線程副本中的值

                account.set(account.get()+money);

            }

            public int getAccount(){

                //返回線程副本中的值

                return account.get();

            }

        }

到此這篇關(guān)于Java實(shí)現(xiàn)線程同步的四種方式總結(jié)的文章就介紹到這了,更多相關(guān)Java線程同步內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • log4j使用教程詳解(怎么使用log4j2)

    log4j使用教程詳解(怎么使用log4j2)

    Log4j 2的好處就不和大家說(shuō)了,如果你搜了2,說(shuō)明你對(duì)他已經(jīng)有一定的了解,并且想用它,所以這里直接就上手了
    2013-12-12
  • Java中的Kotlin?內(nèi)部類原理

    Java中的Kotlin?內(nèi)部類原理

    這篇文章主要介紹了Java中的Kotlin?內(nèi)部類原理,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下
    2022-06-06
  • JavaWeb基礎(chǔ)教程之Java基礎(chǔ)加強(qiáng)版

    JavaWeb基礎(chǔ)教程之Java基礎(chǔ)加強(qiáng)版

    這篇文章主要介紹了JavaWeb基礎(chǔ)教程之Java基礎(chǔ)加強(qiáng)版的相關(guān)資料,需要的朋友可以參考下
    2016-07-07
  • JAVA+Struts2獲取服務(wù)器地址的方法

    JAVA+Struts2獲取服務(wù)器地址的方法

    這篇文章主要介紹了JAVA+Struts2獲取服務(wù)器地址的方法,是Struts2的一個(gè)簡(jiǎn)單應(yīng)用,具有一定的借鑒與參考價(jià)值,需要的朋友可以參考下
    2014-11-11
  • spring?boot?Slf4j日志框架的體系結(jié)構(gòu)詳解

    spring?boot?Slf4j日志框架的體系結(jié)構(gòu)詳解

    在項(xiàng)目開(kāi)發(fā)中記錄日志是必做的一件事情,springboot內(nèi)置了slf4j日志框架,下面這篇文章主要給大家介紹了關(guān)于spring?boot?Slf4j日志框架的體系結(jié)構(gòu),需要的朋友可以參考下
    2022-05-05
  • Spring boot2X負(fù)載均衡和反向代理實(shí)現(xiàn)過(guò)程解析

    Spring boot2X負(fù)載均衡和反向代理實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了Spring boot2X負(fù)載均衡和反向代理實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 扒一扒 Java 中的枚舉類型

    扒一扒 Java 中的枚舉類型

    這篇文章主要給大家介紹了Java中枚舉類型的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • Java利用Spire.XLS for Java實(shí)現(xiàn)在Excel文件中添加或刪除分節(jié)符

    Java利用Spire.XLS for Java實(shí)現(xiàn)在Excel文件中添加或刪除分節(jié)符

    在復(fù)雜的Excel報(bào)表中,合理設(shè)置分節(jié)符能有效提升文檔結(jié)構(gòu)與可讀性,尤其在打印輸出時(shí)效果顯著,本文將深入探討如何利用Spire.XLS for Java輕松實(shí)現(xiàn)Excel分節(jié)符的添加與刪除,希望對(duì)大家有所幫助
    2025-11-11
  • Java中的抽象工廠模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java中的抽象工廠模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    抽象工廠模式是工廠方法模式的升級(jí)版本,他用來(lái)創(chuàng)建一組相關(guān)或者相互依賴的對(duì)象。下面通過(guò)本文給大家分享Java中的抽象工廠模式,感興趣的朋友一起看看吧
    2017-08-08
  • 詳解Java?List中五種常見(jiàn)實(shí)現(xiàn)類的使用

    詳解Java?List中五種常見(jiàn)實(shí)現(xiàn)類的使用

    Java中提供了非常多的使用的List實(shí)現(xiàn)類,本文將重點(diǎn)介紹一下常見(jiàn)的五種實(shí)現(xiàn)類以及他們的應(yīng)用場(chǎng)景,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10

最新評(píng)論

绥中县| 拜城县| 临猗县| 凤城市| 南京市| 宝清县| 大同县| 刚察县| 潮安县| 塔城市| 青岛市| 稻城县| 屯留县| 洪雅县| 买车| 太原市| 微博| 平昌县| 吐鲁番市| 同心县| 毕节市| 嘉定区| 德阳市| 雷山县| 商丘市| 垣曲县| 湘潭县| 来凤县| 阿勒泰市| 凉城县| 大埔县| 司法| 汕头市| 武隆县| 墨竹工卡县| 波密县| 新龙县| 定襄县| 平南县| 阜康市| 马龙县|