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

面试笔记——多线程使用场景

线程池使用场景(CountDownLatch, Future)

CountDownLatch
CountDownLatch(闭锁/倒计时锁)用来进行线程同步协作,等待所有线程完成倒计时(一个或者多个线程,等待其他多个线程完成某件事情之后才能执行)。

  • 构造参数用来初始化等待计数值
  • await() 用来等待计数归零
  • countDown() 用来让计数减一

在这里插入图片描述
上图中,给定初始值count = 3,调用await方法来判断count是否为0,若不为0,则将线程挂起等待,当count等于0之后,该线程才能继续执行。T2,T3,T4执行时,它们都调用了countdown(),每一次调用这个方法,都会对count减一。因此,调用了3次之后,T1线程继续执行。

CountDownLatch的使用demo:

import java.util.concurrent.CountDownLatch;public class CountDownLatchDemo {public static void main(String[] args) throws InterruptedException {//初始化了一个倒计时锁 参数为 3CountDownLatch latch = new CountDownLatch(3);new Thread(() -> {System.out.println(Thread.currentThread().getName()+"-begin...");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}//count--latch.countDown();System.out.println(Thread.currentThread().getName()+"-end..." +latch.getCount());}).start();new Thread(() -> {System.out.println(Thread.currentThread().getName()+"-begin...");try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}//count--latch.countDown();System.out.println(Thread.currentThread().getName()+"-end..." +latch.getCount());}).start();new Thread(() -> {System.out.println(Thread.currentThread().getName()+"-begin...");try {Thread.sleep(1500);} catch (InterruptedException e) {throw new RuntimeException(e);}//count--latch.countDown();System.out.println(Thread.currentThread().getName()+"-end..." +latch.getCount());}).start();String name = Thread.currentThread().getName();System.out.println(name + "-waiting...");//等待其他线程完成latch.await();System.out.println(name + "-wait end...");}}

运行结果:

Thread-0-begin...
Thread-1-begin...
main-waiting...
Thread-2-begin...
Thread-0-end...2
Thread-2-end...1
Thread-1-end...0
main-wait end...

使用场景一——批量导入:
项目上线之前,需要把数据库中的数据一次性的同步到es索引库中,数据可能有1000万左右,一次性读取数据肯定不行(oom异常),可以使用线程池的方式导入,利用CountDownLatch来控制,就能避免一次性加载过多,防止内存溢出:
在这里插入图片描述
在这里插入图片描述
使用场景二——数据汇总:
在一个电商网站中,用户下单之后,需要查询数据,数据包含了三部分:订单信息、包含的商品、物流信息;这三块信息都在不同的微服务中进行实现的,可以通过线程池实现,提升查询效率:
在这里插入图片描述
在实际开发的过程中,难免需要调用多个接口来汇总数据,如果所有接口(或部分接口)的没有依赖关系,就可以使用线程池+future来提升性能。

使用场景三——异步线程:
在很多软件中,都提供了搜索功能,并且会记录用户的搜索记录。在实现搜索功能的时候,不能让搜索功能受到保存搜索记录的影响,通常采取异步的方式来保存搜索记录,通过异步线程来实现该功能。当用户输入关键字开始搜索后,正常返回用户搜索的相关数据,再开一个线程来记录用户的历史记录,并把这个新开的线程放到线程池中去执行。

控制方法允许并发访问的线程数量

Semaphore 信号量,是JUC包下的一个工具类,底层是AQS,我们可以通过其限制执行的线程数量。

使用场景:通常用于那些资源有明确访问数量限制的场景,常用于限流 。

Semaphore使用步骤

  • 创建Semaphore对象,可以给一个容量
  • semaphore.acquire(): 请求一个信号量,这时候的信号量个数-1(一旦没有可使用的信号量,也即信号量个数变为负数时,再次请求的时候就会阻塞,直到其他线程释放了信号量)
  • semaphore.release():释放一个信号量,此时信号量个数+1
import java.util.concurrent.Semaphore;public class SemaphoreCase {public static void main(String[] args) {// 1. 创建 semaphore 对象Semaphore semaphore = new Semaphore(3);// 2. 10个线程同时运行for (int i = 0; i < 10; i++) {new Thread(() -> {try {// 3. 获取许可,计数-1semaphore.acquire();} catch (InterruptedException e) {e.printStackTrace();}try {System.out.println("running...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("end...");} finally {// 4. 释放许可  计数+1semaphore.release();}}).start();}}}

对ThreadLocal的理解

ThreadLocal是多线程中对于解决线程安全的一个操作类,它会为每个线程都分配一个独立的线程副本从而解决了变量并发访问冲突的问题。ThreadLocal 同时实现了线程内的资源共享。

ThreadLocal基本使用:

  • set(value) 设置值——ThreadLocal 自己作为 key,资源对象作为 value,放入当前线程的 ThreadLocalMap 集合中
  • get() 获取值——以 ThreadLocal 自己作为 key,到当前线程中查找关联的资源值
  • remove() 清除值——以 ThreadLocal 自己作为 key,移除当前线程关联的资源值

demo:

public class ThreadLocalTest {static ThreadLocal<String> threadLocal = new ThreadLocal<>();public static void main(String[] args) {new Thread(() -> {String name = Thread.currentThread().getName();threadLocal.set("value1");print(name);System.out.println(name + "-after remove : " + threadLocal.get());}, "t1").start();new Thread(() -> {String name = Thread.currentThread().getName();threadLocal.set("value2");print(name);System.out.println(name + "-after remove : " + threadLocal.get());}, "t2").start();}static void print(String str) {//打印当前线程中本地内存中本地变量的值System.out.println(str + " :" + threadLocal.get());//清除本地内存中的本地变量threadLocal.remove();}}

输出:

t1 :value1
t1-after remove : null
t2 :value2
t2-after remove : null

ThreadLocal本质来说就是一个线程内部存储类,从而让多个线程只操作自己内部的值,从而实现线程数据隔离。
在这里插入图片描述
set方法:
在这里插入图片描述

get方法/remove方法:
在这里插入图片描述
ThreadLocal——内存泄漏

Java对象中的四种引用类型:强引用、软引用、弱引用、虚引用

  • 强引用:最为普通的引用方式,表示一个对象处于有用且必须的状态,如果一个对象具有强引用,则GC并不会回收它。即便堆中内存不足了,宁可出现OOM,也不会对其进行回收。
    • User user = new User();
  • 弱引用:表示一个对象处于可能有用且非必须的状态。在GC线程扫描内存区域时,一旦发现弱引用,就会回收到弱引用相关联的对象。对于弱引用的回收,无关内存区域是否足够,一旦发现则会被回收
    User user = new User(); 
    WeakReference weakReference = new WeakReference(user);
    

每一个Thread维护一个ThreadLocalMap,在ThreadLocalMap中的Entry对象继承了WeakReference。其中key为使用弱引用的ThreadLocal实例,value为线程变量的副本(强引用):

static class Entry extends WeakReference<ThreadLocal<?>> {/** The value associated with this ThreadLocal. */Object value;Entry(ThreadLocal<?> k, Object v) {super(k);value = v;}
}

在这里插入图片描述
避免ThreaLocal内存泄漏——通过remove方法主动释放key、value。

相关文章:

面试笔记——多线程使用场景

线程池使用场景&#xff08;CountDownLatch&#xff0c; Future&#xff09; CountDownLatch CountDownLatch&#xff08;闭锁/倒计时锁&#xff09;用来进行线程同步协作&#xff0c;等待所有线程完成倒计时&#xff08;一个或者多个线程&#xff0c;等待其他多个线程完成某件…...

02.0 基于Verilog控制LED灯每秒钟闪烁一次

本段代码是为Verilog初学者提供的一个名为led_blink简单实例Verilog模块&#xff0c;其功能是控制6个LED灯同步闪烁&#xff0c;每秒钟闪烁一次。 本例代码用于理解时序逻辑的概念&#xff0c;理解多个always模块完全并行执行的概念&#xff0c;讲授时可以与C语言的执行过程进行…...

C语言创建文件夹和多级目录

C调用系统命令创建多级目录 #include <stdio.h> #include <stdlib.h>int main() {const char *path "a/b/c";// 创建目录命令的字符串char mkdir_command[100];sprintf(mkdir_command, "mkdir %s", path);// 调用系统命令system(mkdir_comma…...

2024.5.6

#include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//设置窗口大小this->resize(1000,740);//设置窗口图标this->setWindowIcon(QIcon("C:\\Users\\Administrator\\Desktop\\pictrue\\Plants.png"));//设置窗口标题this-…...

mybatis配置获取自增主键

mybatis配置获取自增主键 【/n】 01 使用场景 当需要刚刚插入数据库的数据对应的新增主键时&#xff0c;通过配置xml文件&#xff0c;使数据库返回新增主键id&#xff0c;并把主键id与类参数对应 02 涉及配置 注解TableId(type IdType.AUTO)&#xff1a;在类主键id通过配…...

完整、免费的把pdf转word文档

在线工具网 https://www.orcc.online 支持pdf转word&#xff0c;免费、完整、快捷 登录网站 https://orcc.online 选择需要转换的pdf文件&#xff1a; 等待转换完成 点击蓝色文件即可下载 无限制&#xff0c;完整转换。...

使用 Lua 协程模拟 Golang 的 go defer 编程模式

封装 go 函数 在 使用 Lua 协程处理异步回调函数 中已经介绍 这里简要列下&#xff1a; 封装 go 函数---go 函数创建并启动一个协程 ---param _co_task function 函数原型 fun(_co:thread) function go(_co_task)local co coroutine.create(_co_task) -- 创建的协程是暂停的…...

网络通信协议,UDP和TCP,初步了解

UDP&#xff08;User Datagram Protocol&#xff09;和TCP&#xff08;Transmission Control Protocol&#xff09;是两种常见的网络通信协议&#xff0c;用于在计算机网络中进行数据传输。 1. TCP&#xff1a;Transmission Control Protocol&#xff08;传输控制协议&#xf…...

Golang | Leetcode Golang题解之第61题旋转链表

题目&#xff1a; 题解&#xff1a; func rotateRight(head *ListNode, k int) *ListNode {if k 0 || head nil || head.Next nil {return head}n : 1iter : headfor iter.Next ! nil {iter iter.Nextn}add : n - k%nif add n {return head}iter.Next headfor add > …...

美业SaaS系统多门店收银系统源码-【分润常见问题】讲解(一)

美业管理系统源码 博弈美业SaaS系统 连锁多门店美业收银系统源码 多门店管理 / 会员管理 / 预约管理 / 排班管理 / 商品管理 / 促销活动 PC管理后台、手机APP、iPad APP、微信小程序 ▶ 分润常见问题&#xff1a; 1、分润金额基数 所有分润计算的基数均为平台订单中各个商…...

Chatbot 在教育中的应用

Chatbot 在教育中的应用 基本信息 ​ 这篇博客主要介绍几篇Chatbot在教育领域中应用的文章&#xff0c;根据文章的侧重点不同&#xff0c;分为介绍教育理论&#xff0c;与介绍系统设计两类。从问题定义、技术方法、教育学理论、实验设计、结论证据几个方面概括各篇文章。 博…...

Apache和Nginx的区别以及如何选择

近来遇到一些客户需要lnmp环境的虚拟主机&#xff0c;但是Hostease这边的虚拟主机都是基于Apache的&#xff0c;尽管二者是不同的服务器软件&#xff0c;但是大多数情况下&#xff0c;通过适当的配置和调整两者程序也是可以兼容的。 目前市面上有许多Web服务器软件&#xff0c;…...

深入探索Element-UI:构建高效Web前端的利器

深入探索Element-UI&#xff1a;构建高效Web前端的利器 引言&#xff1a;前端框架的选择与Element-UI的定位一、Element-UI初探二、快速上手&#xff1a;安装与配置三、核心组件深度解析四、实用功能与进阶技巧五、性能优化与最佳实践六、实战案例分析七、与其他技术栈的集成 安…...

在Ubuntu 24.04 LTS (Noble Numbat)上安装nfs server以及nfs client

在Ubuntu 24.04 LTS (Noble Numbat)上,我使用的是最小化安装, 当然server版本的Ubuntu在安装的时候可能会有网络不通的问题,解决办法见如下文章: ubuntu 24.04 server 仅NAT模式上网设置静态IP设置-CSDN博客文章浏览阅读489次,点赞9次,收藏3次。在Ubuntu 24.04 上设置网…...

供应链|经典论文解读:(s,S) 策略在动态库存下的最优性

文章考虑了具有订购成本&#xff08;由单位成本加上重新订购成本组成&#xff09;的动态库存问题。具体而言&#xff0c;对于每个时期&#xff0c;系统在中期开始是做出一系列采购决策——这些采购有助于库存的积累&#xff0c;并在随后的周期被需求所消耗。每时期系统会产生各…...

Python从0到100(二十):文件读写和文件操作

一、文件的打开和关闭 有了文件系统可以非常方便的通过文件来读写数据&#xff1b;在Python中要实现文件操作是非常简单的。我们可以使用Python内置的open函数来打开文件&#xff0c;在使用open函数时&#xff0c;我们可以通过函数的参数指定文件名、操作模式和字符编码等信息…...

AI+客服行业落地应用

一、客服行业变迁 1.传统客服时代 &#xff08;1&#xff09;客服工作重复性高&#xff0c;技术含量低 &#xff08;2&#xff09;呼出效率低&#xff0c;客服水平参差不齐 &#xff08;3&#xff09;管理难度高&#xff0c;情绪不稳定 &#xff08;4&#xff09;服务质量…...

40 生产者消费者模型

生产者消费者模型 概念 为何要使用生产者消费者模型&#xff0c;这个是用过一个容器解决生产者和消费的强耦合问题。生产者和消费者之间不需要通讯&#xff0c;通过阻塞队列通讯&#xff0c;所以生产者生产完数据之后不用等待消费者处理&#xff0c;直接扔给阻塞队列&#xf…...

QT5之windowswidget_菜单栏+工具栏_核心控件_浮动窗口_模态对话框_标准对话框/文本对话框

菜单栏工具栏 新建工程基类是QMainWindow 1、 2、 3、 点.pro文件&#xff0c;添加配置 因为之后用到lambda&#xff1b; 在.pro文件添加配置c11 CONFIG c11 #不能加分号 添加头文件 #include <QMenuBar>//菜单栏的头文件 主窗口代码mainwindow.cpp文件 #include &q…...

Satellite, Aerial, and Underwater Communication Track(WCSP2023)

1.Dispersion Curve Extraction and Source Localization for Single Hydrophone by Combining Image Skeleton Extraction with Advanced Time-Frequency Analysis(图像骨架提取与先进时频分析相结合的单水听器色散曲线提取和源定位) 摘要&#xff1a;时频分析&#xff08;TF…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...