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

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

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

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

30.1 學習目標與重點提示

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

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

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

30.2.1 分布式鎖的定義

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

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

常見的分布式鎖

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

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

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

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

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

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

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

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

30.3 Spring Boot與分布式鎖的集成

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

30.3.1 集成Redis分布式鎖的步驟

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

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

示例
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文件中的配置:

# 服務器端口
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", "手機", 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", "耳機", 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);
    }
}

應用啟動類:

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();
    }
}

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

30.4 Spring Boot的實際應用場景

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

  • 實現(xià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", "手機", 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", "耳機", 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();
    }
}

輸出結果

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

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

總結

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

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

相關文章

  • 詳解SpringIOC BeanDeifition

    詳解SpringIOC BeanDeifition

    這篇文章主要介紹了SpringIOC BeanDeifition的相關資料,幫助大家更好的理解和學習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)服務監(jiān)控,內容包括Server端服務開發(fā),Client端服務開發(fā)其中Spring?Boot?Admin還可以對其監(jiān)控的服務提供告警功能,如服務宕機時,可以及時以郵件方式通知運維人員,感興趣的朋友跟隨小編一起看看吧
    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),非常不錯,具有參考借鑒價值,感興趣的朋友跟隨腳本之家小編一起學習吧
    2018-05-05
  • Java攔截器、過濾器和監(jiān)聽器的區(qū)別與作用詳解

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

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

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

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

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

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

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

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

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

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

最新評論

松滋市| 京山县| 布拖县| 夹江县| 江陵县| 城固县| 和田市| 突泉县| 桂东县| 岳阳县| 仙游县| 博乐市| 塔河县| 台北县| 搜索| 台中市| 石柱| 河北区| 朔州市| 定兴县| 法库县| 孝义市| 大港区| 台前县| 蒙阴县| 泰顺县| 易门县| 光山县| 临夏县| 岳阳县| 浦北县| 泰州市| 陵水| 咸丰县| 勐海县| 东光县| 比如县| 汝阳县| 云梦县| 德阳市| 肃宁县|