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

模板网站怎么做301/cba赛程

模板网站怎么做301,cba赛程,建安证查询网站,品牌设计公司名称大全一、JUC的常见类 JUC→java.util.concurrent,放了和多线程相关的组件 1.1 Callable 接口 看以下从计算从1加到1000的代码: public class Demo {public static int sum;public static void main(String[] args) throws InterruptedException {Thread …

一、JUC的常见类

JUC→java.util.concurrent,放了和多线程相关的组件

1.1 Callable 接口

看以下从计算从1加到1000的代码:

public class Demo {public static int sum;public static void main(String[] args) throws InterruptedException {Thread t = new Thread(new Runnable() {@Overridepublic void run() {int result = 0;for (int i = 1; i <= 1000; i++) {result += i;}sum = result;}});t.start();t.join();System.out.println(sum);}
}

通过成员变量的方式才能得到线程中任务的最终执行结果,这样会增加代码的耦合性,当改变外部的sum,线程内的sum也要改,所以引入Callable接口

public class Demo {public static void main(String[] args) throws InterruptedException, ExecutionException {Callable<Integer> callable = new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int result = 0;for (int i = 1; i <= 1000; i++) {result += i;}return result;}};FutureTask<Integer> futureTask = new FutureTask<>(callable);Thread t = new Thread(futureTask);t.start();t.join();System.out.println(futureTask.get());}
}

总结:

  1. Callable接口也用来描述一个任务,其中的call方法可以设置返回值将任务执行结果返回
  2. Runnable接口可以用来描述一个任务,但run方法的返回类型为void,无法返回任务结果
  3. callable需要经过FutureTask封装一下才能传入Thread构造方法,否则编译报错

至此创建线程有5种方式:

  1. 继承Thread
  2. 使用Runnable
  3. 使用lambda表达式
  4. 使用线程池/ThreadFactory
  5. 使用Callable接口

2.2 ReentrantLock

ReentrantLock 是可重入锁,它将加锁和解锁两个操作进行了区分,提供了加锁:lock()方法 和解锁:unlock()方法

public class Demo {public static void main(String[] args) {ReentrantLock locker = new ReentrantLock();locker.lock();locker.unlock();}
}

其实这样并不好,因为在加锁和解锁之间可能会存在很多逻辑,假如在解锁之前就通过return返回了,或者抛出了异常,这样走不到解锁,所以一般将unlock写到finally中,finally中的代码无论如何都会被执行

public class Demo {public static void main(String[] args) {ReentrantLock locker = new ReentrantLock();try {locker.lock();} finally {locker.unlock();}}
}

synchronized也是可重入锁,那ReentrantLock相比于synchronized有哪些其他价值?

  1. ReentrantLock 提供了公平锁,向ReentrantLock的构造方法里传入true,就是公平锁,ReentrantLock locker = new ReentrantLock(true);
  2. ReentrantLock提供了tryLock()操作,当尝试加锁,如果所以经被获取了,则返回操作失败,tryLock()还提供了带时间参数版本,可以等待一定时间,时间到了再返回操作失败
  3. synchronized搭配wait notify等待通知机制,ReentrantLock搭配Condition类完成等待通知,Condition可以指定线程唤醒

1.3 信号量 Semaphore

信号量就是一个计数器,描述了可用资源的个数,有两个核心操作:

  • P操作:计数器 -1,申请资源→acquire()
  • V操作:计数器 +1,释放资源→release()
public class Demo {public static void main(String[] args) throws InterruptedException {Semaphore semaphore = new Semaphore(3);semaphore.acquire();semaphore.acquire();semaphore.acquire(); //最多申请3次//semaphore.acquire(); // 这里会进行阻塞, 直到有线程执行release为止semaphore.release(); //释放一个后, 就不会阻塞了semaphore.acquire();}
}

将信号量设为1,其作用就等价于一个锁,当一个线程申请资源后,另外一个线程再申请,就会进入阻塞,直到第一个线程释放资源

public class Demo {public static int count = 0;public static void main(String[] args) throws InterruptedException {Semaphore semaphore = new Semaphore(1);Thread t1 = new Thread(() -> {try {for (int i = 0; i < 50000; i++) {semaphore.acquire();count++;semaphore.release();}} catch (InterruptedException e) {throw new RuntimeException(e);}});Thread t2 = new Thread(() -> {try {for (int i = 0; i < 50000; i++) {semaphore.acquire();count++;semaphore.release();}} catch (InterruptedException e) {throw new RuntimeException(e);}});t1.start();t2.start();t1.join();t2.join();System.out.println("count = "+ count);}
}

1.4 CountDownLatch

当我们把一个任务拆分成多个的时候,当所有的任务(线程)都执行完后将结果合并,此时就可以使用这个工具类来识别所有线程是否都执行完了

public class Demo18 {public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(10); // 配合下面的countDown 和 awaitfor (int i = 0; i < 10; i++) {int id = i;Thread t = new Thread(() -> {System.out.println("线程开始 "+ id);try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("线程结束 "+ id);latch.countDown(); //每个线程执行完都执行一次countDown});t.start();}latch.await(); // 所有线程都执行完countDown 后再往下执行,否则这里阻塞等待System.out.println("所有线程执行结束");}
}

二、集合类的线程安全问题

Vector、Stack、HashTable这三个集合类是线程安全的,因为它们的方法都被synchronized修饰

2.1 多线程使用ArrayList

1)自己使用线程同步机制,加上synchronized或ReentrantLock

2)使用Collections.synchronizedList (new ArrayList);synchronizedList是一个基于synchronized的List,synchronizedList的关键操作上都带有synchronized

3)使用CopyOnWriteArrayList——写时拷贝;当我们向一个容器中插入元素时,会将原容器拷贝出一份新容器,往新容器里插入元素,插入完毕后,将原容器的引用指向新容器

写时拷贝的好处:解决线程安全问题,当在修改时,许多线程也在读,通过写时拷贝的处理,让线程只能在原容器读,在新容器写,写完后,原容器的引用指向新容器

2.2 多线程使用哈希表

HashMap 本身是线程不安全的,在多线程环境下可以使用:Hashtable ConcurrentHashMap

1)Hashtable

在一些关键操作上加上synchronized,这相当于直接针对Hashtable对象本身加锁

  • 多线程访问同一个Hashtable就会造成锁冲突,一个线程使用Hashtable中的关键方法时都会使其他要使用Hashtable的线程进入阻塞
  • Hashtable 一旦触发扩容,就让触发扩容的线程完成整个扩容,效率非常低,因为涉及到大量元素的拷贝

2)ConcurrentHashMap

 ConcurrentHashMap做了一些优化

1)在加锁方式上,使用"锁桶"的方式来代替一把"全局锁",ConcurrentHashMap在哈希表中的每一个链表都加上了锁

这样当两个不同的线程操作不同的链表的时候不会产生锁冲突,这样加了锁而且链表的个数通常很多,大部分情况都不会产生锁冲突,synchronized不产生锁冲突就是个偏向锁

2)size是真个哈希表的属性,不同的线程在执行插入或删除元素时会涉及到多个线程修改同一个变量,所以采用CAS的方式修改size,避免了加锁操作

【注意】这里不要和Hashtable搞混,Hashtable是一把全局锁,一个线程像哈希表中插入元素时,其他线程都在阻塞等待,直到插入完,所以不会涉及到多个线程修改size的情况;但ConcurrentHashMap 是锁桶的方式加锁,针对每个链表加锁,所以会有多个线程同一个时间段插入的情况,那么多个线程修改size的情况就不可避免,因此这里采用CAS的方式修改size

3)ConcurrentHashMap 针对扩容操作做了特殊优化,Hashtable是在触发扩容时,直接在那个线程的put方法里完成整个扩容,而ConcurrentHashMap在扩容会搞一个新数组,这个数组的容量是扩容后的容量

接下来要把旧数组中的数据拷贝到新数组中,但并不是一次性拷贝完,而是在之后,每次有线程进行哈希表的基本操作时,都会把一部分数据从旧数组搬运到新数组

在搬运的过程中:

  • 插入:在新的数组插入
  • 删除:新旧数组都要删除
  • 查找:新就数组都要查找

🙉到此,多线程的篇章全部结束

相关文章:

【JavaEE】多线程(7)

一、JUC的常见类 JUC→java.util.concurrent&#xff0c;放了和多线程相关的组件 1.1 Callable 接口 看以下从计算从1加到1000的代码&#xff1a; public class Demo {public static int sum;public static void main(String[] args) throws InterruptedException {Thread …...

如何高效的向AI大模型提问? - 提示工程Prompt Engineering

大模型的输入&#xff0c;决定了大模型的输出&#xff0c;所以一个符合要求的提问Prompt起到关键作用。 以下是关于提示工程Prompt Engineering主要方法的详细表格&#xff0c;包括每种方法的优点、缺点、应用场景以及具体示例&#xff1a; 主要方法优点缺点应用场景示例明确性…...

4K高清壁纸网站推荐

1. Awesome Wallpapers 官网: https://4kwallpapers.com/ 主题: 创意、摄影、人物、动漫、绘画、视觉 分辨率: 4K Awesome Wallpapers 提供了丰富的高质量图片&#xff0c;分为通用、动漫、人物三大类&#xff0c;可以按屏幕比例和分辨率检索&#xff0c;满足你对壁纸的各种…...

EasyExcel注解使用

上接《Springboot下导入导出excel》&#xff0c;本篇详细介绍 EasyExcel 注解使用。 1. ExcelProperty value&#xff1a;指定写入的列头&#xff0c;如果不指定则使用成员变量的名字作为列头&#xff1b;如果要设置复杂的头&#xff0c;可以为value指定多个值order&#xff…...

Visual Basic 6 关于应用的类库 - 开源研究系列文章

上次整理VB6的原来写的代码&#xff0c;然后遇到了关于应用窗体的显示问题。VB6不比C#&#xff0c;能够直接反射调用里面的方法&#xff0c;判断是否显示关于窗体然后显示。以前写过一个VB6插件的例子&#xff0c;不过那个源码不在&#xff0c;所以就找了度娘&#xff0c;能够象…...

C#泛型

泛型是一种非常强大的特性&#xff0c;它允许程序员编写灵活的代码&#xff0c;同时保持类型安全。泛型的核心思想是允许类或方法在定义时不指定具体的数据类型&#xff0c;而是在实际使用时指定。这意味着你可以创建一个可以与任何数据类型一起工作的类或方法 泛型类通过在类…...

go语言的成神之路-标准库篇-fmt标准库

目录 一、三种类型的输出 print&#xff1a; println&#xff1a; printf&#xff1a; 总结&#xff1a; 代码展示&#xff1a; 二、格式化占位符 %s&#xff1a;用于格式化字符串。 %d&#xff1a;用于格式化整数。 %f&#xff1a;用于格式化浮点数。 %v&#xff1…...

React Native的router解析

写在前面 React Native&#xff08;简称RN&#xff09;是一个由Facebook开发的开源框架&#xff0c;用于构建跨平台的移动应用程序。在RN中&#xff0c;路由&#xff08;router&#xff09;是非常重要的概念&#xff0c;它允许我们在不同的屏幕之间进行导航和切换。 以下是RN…...

Linux update-alternatives 命令详解

1、查看所有候选项 sudo update-alternatives --list &#xff08;java筛选​​​​​​​sudo update-alternatives --list java&#xff09; 2、​​​​​​​更换候选项 sudo update-alternatives --config java 3、自动选择优先级最高的作为默认项 sudo update-alterna…...

【踩坑】修复报错libcurl.so.4、LIBFFI_BASE_7.0、libssl.so.3

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ libcurl.so.4&#xff1a; sudo apt install curl -y LIBFFI_BASE_7.0: conda install libffi3.3 -y libssl.so.3: sudo apt install -y openssl li…...

python网络爬虫基础:html基础概念与遍历文档树

开始之前导入html段落&#xff0c;同时下载好本节将用到的库。下载方式为&#xff1a;pip install beautifulsoup4 一点碎碎念&#xff1a;为什么install后面的不是bs4也不是BeautifulSoup&#xff1f; html_doc """ <html><head><title>The…...

【已解决】MacOS上VMware Fusion虚拟机打不开的解决方法

在使用VMware Fusion时&#xff0c;不少用户可能会遇到虚拟机无法打开的问题。本文将为大家提供一个简单有效的解决方法&#xff0c;只需删除一个文件&#xff0c;即可轻松解决这一问题。 一、问题现象 在MacOS系统上&#xff0c;使用VMware Fusion运行虚拟机时&#xff0c;有…...

经典视觉神经网络1 CNN

一、概述 输入的图像都很大&#xff0c;使用全连接网络的话&#xff0c;计算的代价较高&#xff0c;图像也很难保留原本特征。 卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;是一种专门用于处理具有网格状结构数据的深度学习模型。主要应用…...

一些硬件知识【2024/12/6】

MP6924A: 正点原子加热台拆解&#xff1a; PMOS 相比 NMOS 的缺点&#xff1a; 缺点描述迁移率低PMOS 中的空穴迁移率约为电子迁移率的 1/3 到 1/2&#xff0c;导致导通电流较低。开关速度慢由于迁移率较低&#xff0c;PMOS 的开关速度比 NMOS 慢&#xff0c;不适合高速数字电…...

网络安全法-网络安全支持与促进

第二章 网络安全支持与促进 第十五条 国家建立和完善网络安全标准体系。国务院标准化行政主管部门和国务院其他有关部门根据各自的职责&#xff0c;组织制定并适时修订有关网络安全管理以及网络产品、服务和运行安全的国家标准、行业标准。 国家支持企业、研究机构、高等学…...

【Docker】如何在Docker中配置防火墙规则?

Docker本身并不直接管理防火墙规则&#xff1b;它依赖于主机系统的防火墙设置。不过&#xff0c;Docker在启动容器时会自动配置一些iptables规则来管理容器网络流量。如果你需要更细粒度地控制进出容器的流量&#xff0c;你需要在主机系统上配置防火墙规则。以下是如何在Linux主…...

Cesium 问题: 添加billboard后移动或缩放地球,标记点位置会左右偏移

文章目录 问题分析原先的:添加属性——解决漂移移动问题产生新的问题:所选的经纬度坐标和应放置的位置有偏差解决坐标位置偏差的问题完整代码问题 添加 billboard 后, 分析 原先的: // 图标加载 function addStation ({lon, lat, el, testName...

使用Python3 连接操作 OceanBase数据库

注&#xff1a;使用Python3 连接 OceanBase数据库&#xff0c;可通过安装 PyMySQL驱动包来实现。 本次测试是在一台安装部署OBD的OceanBase 测试linux服务器上&#xff0c;通过python来远程操作OceanBase数据库。 一、Linux服务器通过Python3连接OceanBase数据库 1.1 安装pyth…...

SpringBoot该怎么使用Neo4j - 优化篇

文章目录 前言实体工具使用 前言 上一篇中&#xff0c;我们的Cypher都用的是字符串&#xff0c;字符串拼接简单&#xff0c;但存在写错的风险&#xff0c;对于一些比较懒的开发者&#xff0c;甚至觉得之间写字符串还更自在快速&#xff0c;也确实&#xff0c;但如果在后期需要…...

Flutter如何调用java接口如何导入java包

文章目录 1. Flutter 能直接调用 Java 的接口吗&#xff1f;如何调用 Java 接口&#xff1f; 2. Flutter 能导入 Java 的包吗&#xff1f;步骤&#xff1a; 总结 在 Flutter 中&#xff0c;虽然 Dart 是主要的开发语言&#xff0c;但你可以通过**平台通道&#xff08;Platform …...

Redis 数据结构(一)—字符串、哈希表、列表

Redis&#xff08;版本7.0&#xff09;的数据结构主要包括字符串&#xff08;String&#xff09;、哈希表&#xff08;Hash&#xff09;、列表&#xff08;List&#xff09;、集合&#xff08;Set&#xff09;、有序集合&#xff08;Sorted Set&#xff09;、超日志&#xff08…...

day1:ansible

ansible-doc <module_name>&#xff08;如果没有网&#xff0c;那这个超级有用&#xff09; 这个很有用&#xff0c;用来查单个模块的文档。 ansible-doc -l 列出所有模块 ansible-doc -s <module_name> 查看更详细的模块文档。 ansible-doc --help 使用 --help …...

如何设置Java爬虫的异常处理?

在Java爬虫中设置异常处理是非常重要的&#xff0c;因为网络请求可能会遇到各种问题&#xff0c;如连接超时、服务器错误、网络中断等。通过合理的异常处理&#xff0c;可以确保爬虫的稳定性和健壮性。以下是如何在Java爬虫中设置异常处理的步骤和最佳实践&#xff1a; 1. 使用…...

阿里云盘permission denied

问题是执行 ./aliyunpan 时遇到了 Permission denied 的错误。这通常是因为文件没有执行权限。以下是解决问题的步骤&#xff1a; 检查文件权限 运行以下命令检查文件的权限&#xff1a; ls -l aliyunpan输出中会看到类似以下内容&#xff1a; -rw-r--r-- 1 user group 123…...

在 Ubuntu 24 上安装 Redis 7.0.15 并配置允许所有 IP 访问

前提条件 一台运行 Ubuntu 24 的服务器拥有 sudo 权限的用户 步骤一&#xff1a;更新系统包 首先&#xff0c;确保系统包是最新的&#xff0c;以避免潜在的依赖问题。 sudo apt update sudo apt upgrade -y步骤二&#xff1a;安装编译 Redis 所需的依赖 Redis 需要一些编译…...

构建高效可靠的分布式推理系统:深入解析控制器与模型服务的协同工作

在现代互联网应用中,随着用户需求的增长和技术的进步,单一服务器已经难以满足大规模并发请求的需求。为了提升系统的性能和可靠性,开发者们越来越多地采用分布式架构。本文将结合具体的代码示例,深入浅出地探讨如何构建一个高效的分布式推理系统,并详细解析其中的关键组件…...

springboot394疫情居家办公系统(论文+源码)_kaic

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统疫情居家办公系统信息管理难度大&#xff0c;容错率低&a…...

共筑数字安全防线,2024开源和软件安全沙龙即将启幕

随着数字化转型进程的加快以及开源代码的广泛应用&#xff0c;开源凭借平等、开放、协作、共享的优秀创作模式&#xff0c;逐渐成为推动数字技术创新、加速传统行业转型升级的重要模式。但随着软件供应链日趋复杂多元&#xff0c;使得其安全风险不断加剧&#xff0c;针对软件供…...

后端报错: message: “For input string: \“\““

这个错误信息表明后端尝试将一个空字符串 "" 转换为某种数值类型&#xff08;如整数、长整型等&#xff09;&#xff0c;但转换失败了。在许多编程语言中&#xff0c;如果你试图解析一个非数字的字符串&#xff08;在这个情况下是一个空字符串&#xff09;为数值类型…...

39 矩阵置零

39 矩阵置零 39.1 矩阵置零解决方案 解题思路&#xff1a; 利用第一行和第一列标记&#xff1a; 使用两个标记变量&#xff0c;rowZero和colZero&#xff0c;来判断第一行和第一列是否需要置零。遍历矩阵从(1,1)开始&#xff0c;如果某个元素是0&#xff0c;则标记该行和该列…...