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

Spring Boot 分布式鎖與并發(fā)控制的應(yīng)用場景

 更新時間:2026年03月26日 11:48:47   作者:星辰徐哥  
本章主要介紹了SpringBoot分布式鎖與并發(fā)控制的核心概念與使用方法,包括分布式鎖的定義與特點、并發(fā)控制的定義與特點、SpringBoot與分布式鎖的集成、SpringBoot的實際應(yīng)用場景,感興趣的朋友跟隨小編一起看看吧

Spring Boot 分布式鎖與并發(fā)控制

30.1 學(xué)習(xí)目標(biāo)與重點提示

學(xué)習(xí)目標(biāo):掌握Spring Boot分布式鎖與并發(fā)控制的核心概念與使用方法,包括分布式鎖的定義與特點、并發(fā)控制的定義與特點、Spring Boot與分布式鎖的集成、Spring Boot的實際應(yīng)用場景,學(xué)會在實際開發(fā)中處理分布式鎖與并發(fā)控制問題。
重點:分布式鎖的定義與特點、并發(fā)控制的定義與特點Spring Boot與分布式鎖的集成、Spring Boot的實際應(yīng)用場景

30.2 分布式鎖與并發(fā)控制概述

分布式鎖與并發(fā)控制是Java開發(fā)中的重要組件,用于處理分布式系統(tǒng)中的并發(fā)訪問問題。

30.2.1 分布式鎖的定義

定義:分布式鎖是一種用于在分布式系統(tǒng)中實現(xiàn)資源共享訪問控制的機(jī)制,確保在同一時間只有一個進(jìn)程或線程能夠訪問共享資源。
作用

  • 防止資源的并發(fā)修改。
  • 確保數(shù)據(jù)的一致性。
  • 提高系統(tǒng)的可靠性。

常見的分布式鎖

  • Redis分布式鎖:Redis是一種開源的內(nèi)存數(shù)據(jù)庫,支持分布式鎖。
  • Zookeeper分布式鎖:Zookeeper是一種開源的分布式協(xié)調(diào)服務(wù),支持分布式鎖。
  • Etcd分布式鎖:Etcd是一種開源的分布式鍵值存儲系統(tǒng),支持分布式鎖。

? 結(jié)論:分布式鎖是一種用于在分布式系統(tǒng)中實現(xiàn)資源共享訪問控制的機(jī)制,作用是防止資源的并發(fā)修改、確保數(shù)據(jù)的一致性、提高系統(tǒng)的可靠性。

30.2.2 并發(fā)控制的定義

定義:并發(fā)控制是指在多進(jìn)程或多線程環(huán)境中,控制對共享資源的訪問,防止數(shù)據(jù)不一致和并發(fā)沖突。
作用

  • 防止數(shù)據(jù)不一致。
  • 防止并發(fā)沖突。
  • 提高系統(tǒng)的性能。

常見的并發(fā)控制技術(shù)

  • 鎖機(jī)制:包括悲觀鎖和樂觀鎖。
  • 事務(wù)機(jī)制:包括ACID屬性。
  • 并發(fā)集合:包括ConcurrentHashMap和CopyOnWriteArrayList。

? 結(jié)論:并發(fā)控制是指在多進(jìn)程或多線程環(huán)境中,控制對共享資源的訪問,作用是防止數(shù)據(jù)不一致、防止并發(fā)沖突、提高系統(tǒng)的性能。

30.3 Spring Boot與分布式鎖的集成

Spring Boot與分布式鎖的集成是Java開發(fā)中的重要內(nèi)容。

30.3.1 集成Redis分布式鎖的步驟

定義:集成Redis分布式鎖的步驟是指使用Spring Boot與Redis分布式鎖集成的方法。
步驟

  1. 創(chuàng)建Spring Boot項目。
  2. 添加所需的依賴。
  3. 配置Redis。
  4. 創(chuàng)建分布式鎖工具類。
  5. 創(chuàng)建業(yè)務(wù)層。
  6. 創(chuàng)建控制器類。
  7. 測試應(yīng)用。

示例
pom.xml文件中的依賴:

<dependencies>
    <!-- Web依賴 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Redis依賴 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!-- 測試依賴 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

application.properties文件中的配置:

# 服務(wù)器端口
server.port=8080
# Redis連接信息
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.database=0

分布式鎖工具類:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public class RedisLock {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    private static final String LOCK_KEY = "product-lock";
    private static final long LOCK_EXPIRE_TIME = 30; // 鎖的過期時間,單位秒
    public boolean tryLock(String lockValue) {
        Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(LOCK_KEY, lockValue, LOCK_EXPIRE_TIME, TimeUnit.SECONDS);
        return Boolean.TRUE.equals(result);
    }
    public void releaseLock(String lockValue) {
        String value = stringRedisTemplate.opsForValue().get(LOCK_KEY);
        if (lockValue.equals(value)) {
            stringRedisTemplate.delete(LOCK_KEY);
        }
    }
}

實體類:

public class Product {
    private Long id;
    private String productId;
    private String productName;
    private double price;
    private int stock;
    public Product() {
    }
    public Product(Long id, String productId, String productName, double price, int stock) {
        this.id = id;
        this.productId = productId;
        this.productName = productName;
        this.price = price;
        this.stock = stock;
    }
    // Getter和Setter方法
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getProductId() {
        return productId;
    }
    public void setProductId(String productId) {
        this.productId = productId;
    }
    public String getProductName() {
        return productName;
    }
    public void setProductName(String productName) {
        this.productName = productName;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public int getStock() {
        return stock;
    }
    public void setStock(int stock) {
        this.stock = stock;
    }
    @Override
    public String toString() {
        return "Product{" +
                "id=" + id +
                ", productId='" + productId + '\'' +
                ", productName='" + productName + '\'' +
                ", price=" + price +
                ", stock=" + stock +
                '}';
    }
}

Repository接口:

import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Repository
public class ProductRepository {
    private List<Product> products = new ArrayList<>();
    public ProductRepository() {
        products.add(new Product(1L, "P001", "手機(jī)", 1000.0, 100));
        products.add(new Product(2L, "P002", "電腦", 5000.0, 50));
        products.add(new Product(3L, "P003", "電視", 3000.0, 80));
        products.add(new Product(4L, "P004", "手表", 500.0, 200));
        products.add(new Product(5L, "P005", "耳機(jī)", 300.0, 150));
    }
    public List<Product> getAllProducts() {
        return products;
    }
    public Product getProductById(Long id) {
        return products.stream().filter(product -> product.getId().equals(id)).findFirst().orElse(null);
    }
    public void addProduct(Product product) {
        product.setId((long) (products.size() + 1));
        products.add(product);
    }
    public void updateProduct(Product product) {
        Product existingProduct = getProductById(product.getId());
        if (existingProduct != null) {
            existingProduct.setProductId(product.getProductId());
            existingProduct.setProductName(product.getProductName());
            existingProduct.setPrice(product.getPrice());
            existingProduct.setStock(product.getStock());
        }
    }
    public void deleteProduct(Long id) {
        products.removeIf(product -> product.getId().equals(id));
    }
}

Service類:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.UUID;
@Service
public class ProductService {
    @Autowired
    private ProductRepository productRepository;
    @Autowired
    private RedisLock redisLock;
    public List<Product> getAllProducts() {
        return productRepository.getAllProducts();
    }
    public Product getProductById(Long id) {
        return productRepository.getProductById(id);
    }
    public void addProduct(Product product) {
        productRepository.addProduct(product);
    }
    public void updateProduct(Product product) {
        productRepository.updateProduct(product);
    }
    public void deleteProduct(Long id) {
        productRepository.deleteProduct(id);
    }
    public boolean reduceStock(Long id, int quantity) {
        String lockValue = UUID.randomUUID().toString();
        try {
            if (redisLock.tryLock(lockValue)) {
                Product product = productRepository.getProductById(id);
                if (product != null && product.getStock() >= quantity) {
                    product.setStock(product.getStock() - quantity);
                    productRepository.updateProduct(product);
                    return true;
                }
                return false;
            }
            return false;
        } finally {
            redisLock.releaseLock(lockValue);
        }
    }
}

控制器類:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/products")
public class ProductController {
    @Autowired
    private ProductService productService;
    @GetMapping("/")
    public List<Product> getAllProducts() {
        return productService.getAllProducts();
    }
    @GetMapping("/{id}")
    public Product getProductById(@PathVariable Long id) {
        return productService.getProductById(id);
    }
    @PostMapping("/add")
    public void addProduct(@RequestBody Product product) {
        productService.addProduct(product);
    }
    @PutMapping("/edit/{id}")
    public void editProduct(@PathVariable Long id, @RequestBody Product product) {
        product.setId(id);
        productService.updateProduct(product);
    }
    @DeleteMapping("/delete/{id}")
    public void deleteProduct(@PathVariable Long id) {
        productService.deleteProduct(id);
    }
    @PostMapping("/reduceStock/{id}/{quantity}")
    public boolean reduceStock(@PathVariable Long id, @PathVariable int quantity) {
        return productService.reduceStock(id, quantity);
    }
}

應(yīng)用啟動類:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RedisLockApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisLockApplication.class, args);
    }
}

測試類:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class RedisLockApplicationTests {
    @LocalServerPort
    private int port;
    @Autowired
    private TestRestTemplate restTemplate;
    @Test
    void contextLoads() {
    }
    @Test
    void testGetAllProducts() {
        List products = restTemplate.getForObject("http://localhost:" + port + "/api/products/", List.class);
        assertThat(products).hasSize(5);
    }
    @Test
    void testReduceStock() {
        boolean result = restTemplate.postForObject("http://localhost:" + port + "/api/products/reduceStock/1/10", null, Boolean.class);
        assertThat(result).isTrue();
    }
}

? 結(jié)論:集成Redis分布式鎖的步驟包括創(chuàng)建Spring Boot項目、添加所需的依賴、配置Redis、創(chuàng)建分布式鎖工具類、創(chuàng)建業(yè)務(wù)層、創(chuàng)建控制器類、測試應(yīng)用。

30.4 Spring Boot的實際應(yīng)用場景

在實際開發(fā)中,Spring Boot分布式鎖與并發(fā)控制的應(yīng)用場景非常廣泛,如:

  • 實現(xiàn)產(chǎn)品庫存的并發(fā)扣減。
  • 實現(xiàn)用戶賬戶的并發(fā)扣款。
  • 實現(xiàn)訂單的并發(fā)創(chuàng)建。
  • 實現(xiàn)數(shù)據(jù)的并發(fā)更新。

示例

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.UUID;
@Service
class ProductService {
    @Autowired
    private ProductRepository productRepository;
    @Autowired
    private RedisLock redisLock;
    public List<Product> getAllProducts() {
        return productRepository.getAllProducts();
    }
    public Product getProductById(Long id) {
        return productRepository.getProductById(id);
    }
    public void addProduct(Product product) {
        productRepository.addProduct(product);
    }
    public void updateProduct(Product product) {
        productRepository.updateProduct(product);
    }
    public void deleteProduct(Long id) {
        productRepository.deleteProduct(id);
    }
    public boolean reduceStock(Long id, int quantity) {
        String lockValue = UUID.randomUUID().toString();
        try {
            if (redisLock.tryLock(lockValue)) {
                Product product = productRepository.getProductById(id);
                if (product != null && product.getStock() >= quantity) {
                    product.setStock(product.getStock() - quantity);
                    productRepository.updateProduct(product);
                    return true;
                }
                return false;
            }
            return false;
        } finally {
            redisLock.releaseLock(lockValue);
        }
    }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
class RedisLock {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    private static final String LOCK_KEY = "product-lock";
    private static final long LOCK_EXPIRE_TIME = 30;
    public boolean tryLock(String lockValue) {
        Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(LOCK_KEY, lockValue, LOCK_EXPIRE_TIME, TimeUnit.SECONDS);
        return Boolean.TRUE.equals(result);
    }
    public void releaseLock(String lockValue) {
        String value = stringRedisTemplate.opsForValue().get(LOCK_KEY);
        if (lockValue.equals(value)) {
            stringRedisTemplate.delete(LOCK_KEY);
        }
    }
}
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Repository
class ProductRepository {
    private List<Product> products = new ArrayList<>();
    public ProductRepository() {
        products.add(new Product(1L, "P001", "手機(jī)", 1000.0, 100));
        products.add(new Product(2L, "P002", "電腦", 5000.0, 50));
        products.add(new Product(3L, "P003", "電視", 3000.0, 80));
        products.add(new Product(4L, "P004", "手表", 500.0, 200));
        products.add(new Product(5L, "P005", "耳機(jī)", 300.0, 150));
    }
    public List<Product> getAllProducts() {
        return products;
    }
    public Product getProductById(Long id) {
        return products.stream().filter(product -> product.getId().equals(id)).findFirst().orElse(null);
    }
    public void addProduct(Product product) {
        product.setId((long) (products.size() + 1));
        products.add(product);
    }
    public void updateProduct(Product product) {
        Product existingProduct = getProductById(product.getId());
        if (existingProduct != null) {
            existingProduct.setProductId(product.getProductId());
            existingProduct.setProductName(product.getProductName());
            existingProduct.setPrice(product.getPrice());
            existingProduct.setStock(product.getStock());
        }
    }
    public void deleteProduct(Long id) {
        products.removeIf(product -> product.getId().equals(id));
    }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/products")
class ProductController {
    @Autowired
    private ProductService productService;
    @GetMapping("/")
    public List<Product> getAllProducts() {
        return productService.getAllProducts();
    }
    @GetMapping("/{id}")
    public Product getProductById(@PathVariable Long id) {
        return productService.getProductById(id);
    }
    @PostMapping("/add")
    public void addProduct(@RequestBody Product product) {
        productService.addProduct(product);
    }
    @PutMapping("/edit/{id}")
    public void editProduct(@PathVariable Long id, @RequestBody Product product) {
        product.setId(id);
        productService.updateProduct(product);
    }
    @DeleteMapping("/delete/{id}")
    public void deleteProduct(@PathVariable Long id) {
        productService.deleteProduct(id);
    }
    @PostMapping("/reduceStock/{id}/{quantity}")
    public boolean reduceStock(@PathVariable Long id, @PathVariable int quantity) {
        return productService.reduceStock(id, quantity);
    }
}
@SpringBootApplication
public class RedisLockApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisLockApplication.class, args);
    }
}
// 測試類
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class RedisLockApplicationTests {
    @LocalServerPort
    private int port;
    @Autowired
    private TestRestTemplate restTemplate;
    @Test
    void contextLoads() {
    }
    @Test
    void testGetAllProducts() {
        List products = restTemplate.getForObject("http://localhost:" + port + "/api/products/", List.class);
        assertThat(products).hasSize(5);
    }
    @Test
    void testReduceStock() {
        boolean result = restTemplate.postForObject("http://localhost:" + port + "/api/products/reduceStock/1/10", null, Boolean.class);
        assertThat(result).isTrue();
    }
}

輸出結(jié)果

  • 訪問http://localhost:8080/api/products/:返回所有產(chǎn)品信息。
  • 訪問http://localhost:8080/api/products/reduceStock/1/10:返回true,表示庫存扣減成功。

? 結(jié)論:在實際開發(fā)中,Spring Boot分布式鎖與并發(fā)控制的應(yīng)用場景非常廣泛,需要根據(jù)實際問題選擇合適的分布式鎖和并發(fā)控制方法。

總結(jié)

本章我們學(xué)習(xí)了Spring Boot分布式鎖與并發(fā)控制,包括分布式鎖的定義與特點、并發(fā)控制的定義與特點、Spring Boot與分布式鎖的集成、Spring Boot的實際應(yīng)用場景,學(xué)會了在實際開發(fā)中處理分布式鎖與并發(fā)控制問題。其中,分布式鎖的定義與特點、并發(fā)控制的定義與特點、Spring Boot與分布式鎖的集成、Spring Boot的實際應(yīng)用場景是本章的重點內(nèi)容。從下一章開始,我們將學(xué)習(xí)Spring Boot的其他組件、微服務(wù)等內(nèi)容。

到此這篇關(guān)于Spring Boot 分布式鎖與并發(fā)控制的應(yīng)用場景的文章就介紹到這了,更多相關(guān)Spring Boot 分布式鎖與并發(fā)控制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解SpringIOC BeanDeifition

    詳解SpringIOC BeanDeifition

    這篇文章主要介紹了SpringIOC BeanDeifition的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)springioc,感興趣的朋友可以了解下
    2020-12-12
  • SpringBoot詳解整合Spring?Boot?Admin實現(xiàn)監(jiān)控功能

    SpringBoot詳解整合Spring?Boot?Admin實現(xiàn)監(jiān)控功能

    這篇文章主要介紹了SpringBoot整合Spring?Boot?Admin實現(xiàn)服務(wù)監(jiān)控,內(nèi)容包括Server端服務(wù)開發(fā),Client端服務(wù)開發(fā)其中Spring?Boot?Admin還可以對其監(jiān)控的服務(wù)提供告警功能,如服務(wù)宕機(jī)時,可以及時以郵件方式通知運維人員,感興趣的朋友跟隨小編一起看看吧
    2022-07-07
  • 詳解spring applicationContext.xml 配置文件

    詳解spring applicationContext.xml 配置文件

    本篇文章主要介紹了詳解spring applicationContext.xml 配置文件 ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • POST方法給@RequestBody傳參數(shù)失敗的解決及原因分析

    POST方法給@RequestBody傳參數(shù)失敗的解決及原因分析

    這篇文章主要介紹了POST方法給@RequestBody傳參數(shù)失敗的解決及原因分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring 框架中注入或替換方法實現(xiàn)

    Spring 框架中注入或替換方法實現(xiàn)

    這篇文章主要介紹了Spring 框架中注入或替換方法實現(xiàn),非常不錯,具有參考借鑒價值,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-05-05
  • Java攔截器、過濾器和監(jiān)聽器的區(qū)別與作用詳解

    Java攔截器、過濾器和監(jiān)聽器的區(qū)別與作用詳解

    Java 攔截器、過濾器和監(jiān)聽器是在 Java Web 開發(fā)中常用的組件,它們各有特點和用途,下面將分別介紹它們的區(qū)別和作用,并提供具體的代碼示例,需要的朋友可以參考下
    2025-06-06
  • maven三個常用的插件使用介紹

    maven三個常用的插件使用介紹

    大家好,本篇文章主要講的是maven三個常用的插件使用介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • MyBatis嵌套查詢collection報錯:org.apache.ibatis.exceptions.TooManyResultsException

    MyBatis嵌套查詢collection報錯:org.apache.ibatis.exceptions.TooMany

    本文主要介紹了MyBatis嵌套查詢collection報錯:org.apache.ibatis.exceptions.TooManyResultsException,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-09-09
  • Docker環(huán)境下Spring Boot應(yīng)用內(nèi)存飆升分析與解決場景分析

    Docker環(huán)境下Spring Boot應(yīng)用內(nèi)存飆升分析與解決場景分析

    當(dāng)運行一個Spring Boot項目時,如果未設(shè)置JVM內(nèi)存參數(shù),Spring Boot默認(rèn)會采用JVM自身默認(rèn)的配置策略,接下來通過本文給大家介紹Docker環(huán)境下Spring Boot應(yīng)用內(nèi)存飆升分析與解決方法,需要的朋友參考下吧
    2021-08-08
  • Java實現(xiàn)PDF轉(zhuǎn)圖片的三種方法

    Java實現(xiàn)PDF轉(zhuǎn)圖片的三種方法

    有些時候我們需要在項目中展示PDF,所以我們可以將PDF轉(zhuǎn)為圖片,然后已圖片的方式展示,效果很好,Java使用各種技術(shù)將pdf轉(zhuǎn)換成圖片格式,并且內(nèi)容不失幀,本文給大家介紹了三種方法實現(xiàn)PDF轉(zhuǎn)圖片的案例,需要的朋友可以參考下
    2023-10-10

最新評論

怀远县| 沁源县| 东乌珠穆沁旗| 余姚市| 安宁市| 临夏县| 大洼县| 游戏| 根河市| 宣汉县| 沙河市| 穆棱市| 古丈县| 麟游县| 三江| 托克托县| 娱乐| 封开县| 峨眉山市| 定兴县| 乌拉特中旗| 马尔康县| 贵阳市| 湘乡市| 梁山县| 澄城县| 崇左市| 贵溪市| 双城市| 乌鲁木齐市| 东安县| 平果县| 麻栗坡县| 新蔡县| 德令哈市| 凤山县| 凤阳县| 墨竹工卡县| 湘阴县| 汉阴县| 青龙|