欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于Java中的CAS如何使用

 更新時(shí)間:2023年09月01日 10:27:03   作者:程序員徐師兄  
這篇文章主要介紹了關(guān)于Java中的CAS如何使用,CAS是Compare And Swap(比較并交換)的縮寫(xiě),是一種非阻塞式并發(fā)控制技術(shù),用于保證多個(gè)線(xiàn)程在修改同一個(gè)共享資源時(shí)不會(huì)出現(xiàn)競(jìng)爭(zhēng)條件,從而避免了傳統(tǒng)鎖機(jī)制的各種問(wèn)題,需要的朋友可以參考下

什么是CAS?

在Java中,CAS主要是通過(guò)java.util.concurrent.atomic包下的一些類(lèi)和方法來(lái)實(shí)現(xiàn)的,下面我們就來(lái)詳細(xì)了解一下CAS及其在Java中的使用。

CAS是一種非阻塞式并發(fā)控制技術(shù),它主要用于解決多個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn)同一個(gè)共享資源時(shí)可能出現(xiàn)的競(jìng)爭(zhēng)條件問(wèn)題。

為了保證數(shù)據(jù)的一致性和正確性,我們通常需要采取同步機(jī)制來(lái)對(duì)共享資源進(jìn)行加鎖。

但是,傳統(tǒng)的鎖機(jī)制在高并發(fā)場(chǎng)景下會(huì)帶來(lái)嚴(yán)重的性能問(wèn)題,因?yàn)樗芯€(xiàn)程都需要等待鎖的釋放才能進(jìn)行操作,這就會(huì)導(dǎo)致大量線(xiàn)程的阻塞和喚醒,進(jìn)而降低了系統(tǒng)的并發(fā)性能。

為了解決這個(gè)問(wèn)題,CAS應(yīng)運(yùn)而生。

它是一種無(wú)鎖的同步機(jī)制,可以在不使用鎖的情況下實(shí)現(xiàn)數(shù)據(jù)的同步和并發(fā)控制。

CAS的核心思想是:在執(zhí)行操作之前,先比較當(dāng)前內(nèi)存中的值是否等于期望值,如果相等,則執(zhí)行修改操作;

如果不相等,則不執(zhí)行修改操作,繼續(xù)進(jìn)行比較,直到內(nèi)存中的值與期望值相等為止。

這個(gè)過(guò)程中不會(huì)出現(xiàn)線(xiàn)程的阻塞和喚醒,因此可以提高系統(tǒng)的并發(fā)性能。

Java中的CAS

在Java中,CAS主要是通過(guò)java.util.concurrent.atomic包下的一些類(lèi)和方法來(lái)實(shí)現(xiàn)的。這些類(lèi)和方法提供了一種原子操作的方式,可以保證多個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn)同一個(gè)共享資源時(shí)不會(huì)出現(xiàn)競(jìng)爭(zhēng)條件。

AtomicBoolean

AtomicBoolean類(lèi)表示一個(gè)布爾類(lèi)型的原子變量,它提供了一些原子操作方法

例如compareAndSet、getAndSet、weakCompareAndSet等,可以保證對(duì)該變量的操作是原子的。

下面是一個(gè)示例代碼:

import java.util.concurrent.atomic.AtomicBoolean;
public class AtomicBooleanTest {
    private static AtomicBoolean flag = new AtomicBoolean(false);
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while (!flag.compareAndSet(false, true)) {
                System.out.println(Thread.currentThread().getName() + ": try again");
            }
            System.out.println(Thread.currentThread().getName() + ": success");
        },"Thread-1");
        Thread t2 = new Thread(() -> {
            while (!flag.compareAndSet(false, true)) {
                System.out.println(Thread.currentThread().getName() + ": try again");
            }
            System.out.println(Thread.currentThread().getName() + ": success");
        },"Thread-2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}

在這個(gè)例子中,我們創(chuàng)建了一個(gè)AtomicBoolean類(lèi)型的變量flag,并定義了兩個(gè)線(xiàn)程t1和t2,它們都會(huì)不斷地嘗試將flag的值由false變?yōu)閠rue,直到成功為止。如果兩個(gè)線(xiàn)程同時(shí)嘗試修改flag的值,只有一個(gè)線(xiàn)程能夠獲得成功,另一個(gè)線(xiàn)程會(huì)繼續(xù)嘗試,直到成功為止。

AtomicInteger

AtomicInteger類(lèi)表示一個(gè)整型的原子變量,它提供了一些原子操作方法,例如compareAndSet、getAndSet、incrementAndGet等,可以保證對(duì)該變量的操作是原子的。

下面是一個(gè)示例代碼:

import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerTest {
    private static AtomicInteger count = new AtomicInteger(0);
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (int i = 0;i < 10000; i++) {
                count.incrementAndGet();
            }
        },"Thread-1");
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) {
                count.incrementAndGet();
            }
        },"Thread-2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("count = " + count.get());
    }
}

在這個(gè)例子中,我們創(chuàng)建了一個(gè)AtomicInteger類(lèi)型的變量count,并定義了兩個(gè)線(xiàn)程t1和t2,它們都會(huì)對(duì)count進(jìn)行一萬(wàn)次的自增操作。由于AtomicInteger提供的incrementAndGet方法是原子的,因此多個(gè)線(xiàn)程同時(shí)對(duì)count進(jìn)行自增操作不會(huì)出現(xiàn)競(jìng)爭(zhēng)條件,最終count的值會(huì)是正確的。

AtomicReference

AtomicReference類(lèi)表示一個(gè)引用類(lèi)型的原子變量,它提供了一些原子操作方法,例如compareAndSet、getAndSet、weakCompareAndSet等,可以保證對(duì)該變量的操作是原子的。

下面是一個(gè)示例代碼:

import java.util.concurrent.atomic.AtomicReference;
public class AtomicReferenceTest {
    private static class Student{
        private String name;
        private int age;
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
        public void setName(String name) {
            this.name = name;
        }
        public void setAge(int age) {
            this.age = age;
        }
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    private static AtomicReference<Student> student = new AtomicReference<>(new Student("張三", 18));
    public static void main(String[] args) {
        Student newStudent = new Student("李四", 20);
        student.compareAndSet(student.get(), newStudent);
        System.out.println(student.get());
    }
}

在這個(gè)例子中,我們創(chuàng)建了一個(gè)AtomicReference類(lèi)型的變量student,并定義了一個(gè)Student類(lèi)型的對(duì)象newStudent。

我們通過(guò)compareAndSet方法將原子變量student的值從原來(lái)的Student對(duì)象修改為newStudent對(duì)象,由于AtomicReference提供的compareAndSet方法是原子的,因此多個(gè)線(xiàn)程同時(shí)對(duì)student進(jìn)行修改操作不會(huì)出現(xiàn)競(jìng)爭(zhēng)條件。

總結(jié)

CAS是一種非阻塞式的并發(fā)控制技術(shù),它可以在不使用鎖的情況下實(shí)現(xiàn)數(shù)據(jù)的同步和并發(fā)控制,從而提高系統(tǒng)的并發(fā)性能。

在Java中,CAS主要是通過(guò)java.util.concurrent.atomic包下的一些類(lèi)和方法來(lái)實(shí)現(xiàn)的,它們提供了一種原子操作的方式,可以保證多個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn)同一個(gè)共享資源時(shí)不會(huì)出現(xiàn)競(jìng)爭(zhēng)條件。

實(shí)際開(kāi)發(fā)中,如果需要對(duì)共享資源進(jìn)行并發(fā)控制,建議優(yōu)先考慮使用CAS技術(shù)。

到此這篇關(guān)于關(guān)于Java中的CAS如何使用的文章就介紹到這了,更多相關(guān)Java中的CAS內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java線(xiàn)程監(jiān)聽(tīng),意外退出線(xiàn)程后自動(dòng)重啟的實(shí)現(xiàn)方法

    Java線(xiàn)程監(jiān)聽(tīng),意外退出線(xiàn)程后自動(dòng)重啟的實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇Java線(xiàn)程監(jiān)聽(tīng),意外退出線(xiàn)程后自動(dòng)重啟的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • Fluent Mybatis快速入門(mén)詳細(xì)教程

    Fluent Mybatis快速入門(mén)詳細(xì)教程

    由于FluentMybatis是基于mybatis上做封裝和擴(kuò)展的,所以這里主要聊聊mybatis處理的方式,以及給出FluentMybatis的解放方案。對(duì)Fluent Mybatis入門(mén)相關(guān)知識(shí)感興趣的朋友一起看看吧
    2021-08-08
  • 淺談java異常處理之空指針異常

    淺談java異常處理之空指針異常

    下面小編就為大家?guī)?lái)一篇淺談java異常處理之空指針異常。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-10-10
  • Java實(shí)現(xiàn)批量查找與替換Excel文本的思路詳解

    Java實(shí)現(xiàn)批量查找與替換Excel文本的思路詳解

    在 Java 中,可以通過(guò)find和replace的方法來(lái)查找和替換單元格的數(shù)據(jù),下面小編將以Excel文件為例為大家介紹如何實(shí)現(xiàn)Excel文件內(nèi)容的批量替換,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • mvn compile報(bào)錯(cuò)“程序包c(diǎn)om.XXX不存在”

    mvn compile報(bào)錯(cuò)“程序包c(diǎn)om.XXX不存在”

    本文主要介紹了mvn compile報(bào)錯(cuò)“程序包c(diǎn)om.XXX不存在”,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Spring的事件監(jiān)聽(tīng)機(jī)制示例詳解

    Spring的事件監(jiān)聽(tīng)機(jī)制示例詳解

    這篇文章主要給大家介紹了關(guān)于Spring的事件監(jiān)聽(tīng)機(jī)制的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • Java成員變量默認(rèn)值原理詳解

    Java成員變量默認(rèn)值原理詳解

    這篇文章主要介紹了Java成員變量默認(rèn)值原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • ZooKeeper官方文檔之Java案例解讀

    ZooKeeper官方文檔之Java案例解讀

    ZooKeeper官方提供了一個(gè)Java監(jiān)聽(tīng)的例子,本文是我對(duì)該例子的學(xué)習(xí)筆記??梢宰鰹閹椭斫獯死拥馁Y料,有需要的朋友可以借鑒參考下
    2022-01-01
  • Java實(shí)現(xiàn)向數(shù)組里添加元素

    Java實(shí)現(xiàn)向數(shù)組里添加元素

    這篇文章主要介紹了Java實(shí)現(xiàn)向數(shù)組里添加元素方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • redis與spring整合使用的步驟實(shí)例教程

    redis與spring整合使用的步驟實(shí)例教程

    這篇文章主要給大家介紹了關(guān)于redis與spring整合使用的相關(guān)資料,文中通過(guò)示例代碼將實(shí)現(xiàn)的步驟一步步介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03

最新評(píng)論