当前位置: 首页 > wzjs >正文

网站咋做网络游戏推广怎么做

网站咋做,网络游戏推广怎么做,朋友要给我做网站,梅州网站建设公司思维导图: 在 Spring Boot 里,默认情况下 Bean 是单例的。单例 Bean 意味着在整个应用程序上下文里只有一个实例。要是这个单例 Bean 有状态(也就是包含实例变量),而且多个线程同时对这些实例变量进行读写操作&#xf…

 思维导图:

  在 Spring Boot 里,默认情况下 Bean 是单例的。单例 Bean 意味着在整个应用程序上下文里只有一个实例。要是这个单例 Bean 有状态(也就是包含实例变量),而且多个线程同时对这些实例变量进行读写操作,就可能产生线程安全问题。下面是一个具体的示例。


1. 创建 Spring Boot 项目

可以使用 Spring Initializr(https://start.spring.io/)创建一个包含 Spring Web 依赖的 Spring Boot 项目。

2. 定义有状态的单例 Bean

创建一个 CounterService 类,它有一个实例变量 count,还有两个方法分别用于增加计数和获取计数。

package com.example.demo.service;import org.springframework.stereotype.Service;@Service
public class CounterService {private int count = 0;public void increment() {try {// 模拟耗时操作,放大线程安全问题Thread.sleep(1);} catch (InterruptedException e) {Thread.currentThread().interrupt();}count++; // 非原子操作,多线程下易出现问题}public int getCount() {return count;}
}

 3. 创建控制器来调用 Bean

创建一个 CounterController 类,它会注入 CounterService中的 Bean,并且提供两个端点,一个用于增加计数,另一个用于获取计数。

package com.example.demo.controller;import com.example.demo.service.CounterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user")
public class CounterController {@Autowiredprivate CounterService counterService;@GetMapping("/increment")public String increment() {counterService.increment();return "Count incremented";}@GetMapping("/count")public int getCount() {return counterService.getCount();}
}

4. 测试线程安全问题

可以使用多线程工具(如 Apache JMeter 或者编写一个简单的 Java 多线程程序)来模拟多个线程同时访问 /increment 端点。以下是一个简单的 Java 多线程测试代码:

package com.example.demo;import com.example.demo.service.CounterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;@SpringBootApplication
public class DemoApplication implements CommandLineRunner {@Autowiredprivate CounterService counterService;public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}@Overridepublic void run(String... args) throws Exception {ExecutorService executorService = Executors.newFixedThreadPool(50); // 50 个线程并发int threadCount = 1000;for (int i = 0; i < threadCount; i++) {executorService.submit(() -> counterService.increment());}executorService.shutdown();while (!executorService.isTerminated()) {// 等待所有任务完成}System.out.println("Expected count: " + threadCount); // 预期 1000System.out.println("Actual count: " + counterService.getCount()); // 实际值很可能小于 1000}
}

原理分析

count++ 操作由 “读取 count 值 → 对值加 1 → 写回新值” 三个步骤组成,并非原子操作。
当多个线程执行到 Thread.sleep(1) 时,会释放 CPU 时间片,其他线程可能在此时读取到相同的 count 值,导致最终结果小于预期(如 998、990 等),从而体现出单例 Bean(有状态且无同步措施)的线程安全问题。

 

解决方案

在 Spring Boot 中,若单例 Bean 存在状态(如包含可变成员变量),需通过以下方式解决线程安全问题:

1. 同步机制(如 synchronized

通过对方法或代码块加锁,确保同一时间只有一个线程执行关键代码。

import org.springframework.stereotype.Service;@Service
public class CounterService {private int count = 0;// 对方法加锁,保证原子性public synchronized void increment() {count++;}public int getCount() {return count;}
}

原理:synchronized 会在方法或代码块执行时获取锁,其他线程需等待锁释放,避免多个线程同时修改共享变量。

2. 使用原子类(如 AtomicInteger

Java 并发包 java.util.concurrent.atomic 提供的原子类,其方法(如 incrementAndGet)内部通过底层机制(如 CAS)保证操作原子性。

import org.springframework.stereotype.Service;
import java.util.concurrent.atomic.AtomicInteger;@Service
public class CounterService {private AtomicInteger count = new AtomicInteger(0);public void increment() {count.incrementAndGet(); // 原子操作}public int getCount() {return count.get();}
}

 原理:原子类通过硬件级别的原子操作或乐观锁(CAS)确保对变量的修改是线程安全的,避免传统锁的性能开销。

3. ThreadLocal 隔离线程变量

为每个线程提供独立的变量副本,避免线程间共享数据。

import org.springframework.stereotype.Service;@Service
public class CounterService {private ThreadLocal<Integer> count = ThreadLocal.withInitial(() -> 0);public void increment() {count.set(count.get() + 1); // 操作当前线程的副本}public int getCount() {return count.get();}// 建议在使用后清理,防止内存泄漏public void clean() {count.remove();}
}

4. 修改 Bean 作用域为 prototype

将单例(singleton)改为原型(prototype),每次请求都会创建新的 Bean 实例,避免多线程共享状态。

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;@Service
@Scope("prototype") // 每次请求创建新实例
public class CounterService {private int count = 0;public void increment() {count++;}public int getCount() {return count;}
}

原理:原型作用域下,每个线程获取独立的 Bean 实例,线程间无共享状态,从而避免线程安全问题,但会增加对象创建开销。

  实际应用中,可根据场景选择:

  • 简单场景优先用 原子类(性能高)或 同步方法(实现简单)。
  • 若变量需线程内共享但跨线程隔离,用 ThreadLocal
  • 若 Bean 实例创建开销小且需彻底隔离,用 prototype 作用域

http://www.dtcms.com/wzjs/110767.html

相关文章:

  • 深圳做网站龙华新科湖南中高风险地区
  • 衡天主机怎么做网站微博付费推广有用吗
  • 动态网站开发试题百度账号人工申诉
  • 视频直播网站如何做免费推广有哪些
  • 做网站学好哪些软件广东网站seo策划
  • 某景区网站建设策划书百度指数的主要功能有
  • 深圳最好的区排名杭州网站优化企业
  • 做网站需要申请商标哪些类目网站制作公司怎么样
  • 做财经直播网站红河网站建设
  • 做网站什么框架方便开发网站的流程是
  • 短视频推广的优势天津关键词优化专家
  • 电子商务网站建设实训总结报告影响seo排名的因素有哪些
  • crm系统怎么用seo 页面
  • 建设部网站建造师公示宁波网站推广网站优化
  • 好的做蛋糕网站seo是什么意思职业
  • 马鞍山市网站建设公司搜一搜搜索
  • 深喉咙企业网站系统q群排名优化软件
  • 动态网页设计网站建设2022最近比较火的热点话题
  • 企业融资计划书seo入门书籍推荐
  • 吉林电商网站建设价格宁德seo公司
  • 网站基本模板海南seo快速排名优化多少钱
  • 网站后台域名解析怎么做磁力搜索引擎不死鸟
  • 智能模板网站建设百度搜索词热度查询
  • 好男人新资源在线播放标题seo是什么意思
  • 网站架设流程如何做电商
  • 六年级做网站的软件百度经验悬赏令
  • 什么是网站模板搜索引擎优化seo是什么
  • 动态网站设计与开发新闻头条最新消息10条
  • 做网站费用百度搜索热度排名
  • 古建设工程造价管理协会网站seo外链平台热狗