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

Java線(xiàn)程同步的四種方式詳解

 更新時(shí)間:2023年02月18日 16:05:22   投稿:wdc  
這篇文章主要介紹了Java線(xiàn)程同步的四種方式詳解,需要的朋友可以參考下

Java線(xiàn)程同步屬于Java多線(xiàn)程與并發(fā)編程的核心點(diǎn),需要重點(diǎn)掌握,下面我就來(lái)詳解Java線(xiàn)程同步的4種主要的實(shí)現(xiàn)方式

什么是Java線(xiàn)程同步

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

Java線(xiàn)程同步的四種方式詳解(建議收藏)-mikechen的互聯(lián)網(wǎng)架構(gòu)

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

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

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

Java線(xiàn)程同步的幾種方式

Java線(xiàn)程同步的四種方式詳解(建議收藏)-mikechen的互聯(lián)網(wǎng)架構(gòu)

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

這種方式比較靈活,修飾一個(gè)代碼塊,被修飾的代碼塊稱(chēng)為同步語(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 + "賬戶(hù)余額為:" + bank.getAccount());
            }
        }
 
    }
 
    /**
     * 建立線(xiàn)程,調(diào)用內(nèi)部類(lèi)
     */
    public void useThread() {
        Bank bank = new Bank();
        NewThread new_thread = new NewThread(bank);
        System.out.println("線(xiàn)程1");
        Thread thread1 = new Thread(new_thread);
        thread1.start();
        System.out.println("線(xiàn)程2");
        Thread thread2 = new Thread(new_thread);
        thread2.start();
    }
 
    public static void main(String[] args) {
        SynchronizedThread st = new SynchronizedThread();
        st.useThread();
    }
 
}

2.使用ReentrantLock

ReentrantLock類(lèi)是可重入、互斥、實(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)度線(xiàn)程,線(xiàn)程更好,并且具有更好的擴(kuò)展性(提供更多的子類(lèi));

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

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

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

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

比如典型代表:AtomicInteger類(lèi)存在于java.util.concurrent.atomic中,該類(lèi)表示支持原子操作的整數(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)線(xiàn)程同步

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

具體代碼示例如下:

//只改Bank類(lèi),其余代碼與上同
public class Bank{
    // 創(chuàng)建一個(gè)線(xiàn)程本地變量 ThreadLocal
    private static ThreadLocal<Integer> account = new ThreadLocal<Integer>(){
        @Override
        //返回當(dāng)前線(xiàn)程的"初始值" 
        protected Integer initialValue(){
            return 100;
        }
    };
    public void save(int money){
        //設(shè)置線(xiàn)程副本中的值
        account.set(account.get()+money);
    }
    public int getAccount(){
        //返回線(xiàn)程副本中的值 
        return account.get();
    }
}

以上就是Java線(xiàn)程同步的四種方式詳解的詳細(xì)內(nèi)容,更多關(guān)于Java線(xiàn)程同步的四種方式詳解的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java中的小知識(shí)點(diǎn)總結(jié)

    Java中的小知識(shí)點(diǎn)總結(jié)

    最近在復(fù)習(xí)Java的基礎(chǔ),遇到了一些比較偏的考核題目,特地總結(jié)一下需要注意的知識(shí)點(diǎn)!不過(guò)在使用IDE編程的時(shí)候,這些問(wèn)題都會(huì)馬上被IDE識(shí)別出來(lái),編譯是通不過(guò)的。我在這里提出來(lái)就相當(dāng)于給初學(xué)者一些貢獻(xiàn)吧
    2013-07-07
  • Springboot中如何通過(guò)yml為實(shí)體類(lèi)注入屬性

    Springboot中如何通過(guò)yml為實(shí)體類(lèi)注入屬性

    這篇文章主要介紹了Springboot中如何通過(guò)yml為實(shí)體類(lèi)注入屬性,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • java實(shí)戰(zhàn)之桌球小游戲

    java實(shí)戰(zhàn)之桌球小游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)戰(zhàn)之桌球小游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • MyBatisPlus自定義SQL的實(shí)現(xiàn)

    MyBatisPlus自定義SQL的實(shí)現(xiàn)

    MyBatisPlus提供了自定義SQL功能,允許開(kāi)發(fā)者在Mapper接口中定義方法,并通過(guò)XML文件或注解編寫(xiě)SQL語(yǔ)句,本文詳解了如何在MP中使用自定義SQL,感興趣的可以了解一下
    2024-09-09
  • Spring的IOC原理詳情

    Spring的IOC原理詳情

    這篇文章主要介紹了Spring的IOC原理詳情,IOC是Inversion?of?Control的縮寫(xiě),多數(shù)書(shū)籍翻譯成“控制反轉(zhuǎn)”,還有些書(shū)籍翻譯成為控制反向或者控制倒置
    2022-07-07
  • Java 繼承與多態(tài)的深入理解

    Java 繼承與多態(tài)的深入理解

    這篇文章主要介紹了Java 繼承與多態(tài)的深入理解的相關(guān)資料,子類(lèi)繼承父類(lèi)的特征和行為,使得子類(lèi)具有父類(lèi)的各種屬性和方法?;蜃宇?lèi)從父類(lèi)繼承方法,使得子類(lèi)具有父類(lèi)相同的行為,需要的朋友可以參考下
    2017-08-08
  • JavaEE中關(guān)于ServletConfig的小結(jié)

    JavaEE中關(guān)于ServletConfig的小結(jié)

    ServletConfig是針對(duì)特定的Servlet的參數(shù)或?qū)傩?。ServletConfig是表示單獨(dú)的Servlet的配置和參數(shù),只是適用于特定的Servlet。從一個(gè)servlet被實(shí)例化后,對(duì)任何客戶(hù)端在任何時(shí)候訪(fǎng)問(wèn)有效,但僅對(duì)本servlet有效,一個(gè)servlet的ServletConfig對(duì)象不能被另一個(gè)servlet訪(fǎng)問(wèn)
    2014-10-10
  • Spring中一個(gè)少見(jiàn)的引介增強(qiáng)IntroductionAdvisor

    Spring中一個(gè)少見(jiàn)的引介增強(qiáng)IntroductionAdvisor

    這篇文章主要為大家介紹了Spring中一個(gè)少見(jiàn)的引介增強(qiáng)IntroductionAdvisor實(shí)戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 深入解析@InitBinder注解的功能與應(yīng)用

    深入解析@InitBinder注解的功能與應(yīng)用

    這篇文章主要介紹了深入解析@InitBinder注解的功能與應(yīng)用,從字面意思可以看出這個(gè)的作用是給Binder做初始化的,被此注解的方法可以對(duì)WebDataBinder初始化,webDataBinder是用于表單到方法的數(shù)據(jù)綁定的,需要的朋友可以參考下
    2023-10-10
  • java獲取文件大小的幾種方法

    java獲取文件大小的幾種方法

    這篇文章主要介紹了java獲取文件大小的幾種方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10

最新評(píng)論