Java EE 多线程之 JUC

文章目录

  • 1. Callable 接口
  • 2. ReentrantLock
  • 3. 信号量
  • 4. CountDownLatch

JUC这里就是指(java.util.concurrent)
concurrent 就是并发的意思
这个包里的内容,主要就是一些多线程相关的组件

1. Callable 接口

Callable 也是一种创建线程的方式
适合与想让某个线程执行一个逻辑,并且返回结果的时候
相比之下,Runnable 不关注结果

在这里插入图片描述
这个和Runnable 方法很像
call 方法是 Callable 中的核心方法
返回值就是 Integer,期望值这个线程能够返回一个整数

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class ThreadDemo35 {public static void main(String[] args) throws ExecutionException, InterruptedException {//定义了任务Callable<Integer> callable = new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 0; i <= 1000; i++) {sum += i;}return sum;}};//把任务放到线程中进行执行FutureTask<Integer> futureTask = new FutureTask<>(callable);Thread t = new Thread(futureTask);t.start();//此处的 get 就能获取到 callable 里面的返回结果//由于线程是并发执行的,执行到主线的 get 的时候,t 线程可能还没执行完//没执行完的话,get 就会阻塞System.out.println(futureTask.get());}
}

在这里插入图片描述
futureTask 在这里就是相当于让一个线程跑起来,我们来等待结果

就相当于去吃饭,扫码点单后会给你一个小票,可以凭小票取餐
点餐完成后,后厨就相当于一个线程,就开始执行了
这个过程中,我们需要等出餐
等餐好了,就可以那小票取餐

这个时候 futureTask 就相当于拿着小票换执行结果


这个时候我们创建线程的方式有增加了一种

线程创建的方式:

  1. 继承 Thread,重写 run(创建单独的类,也可以匿名内部类)
  2. 实现 Runnable,重写 run(创建单独的类,也可以匿名内部类)
  3. 实现 Callable,重写 call(创建单独的类,也可以匿名内部类)
  4. 使用 lambda 表达式
  5. ThreadFactory 线程工厂
  6. 线程池

2. ReentrantLock

可重⼊互斥锁,和 synchronized 定位类似,都是⽤来实现互斥效果,保证线程安全

ReentrantLock 的⽤法:
• lock():加锁,如果获取不到锁就死等
• trylock(超时时间):加锁,如果获取不到锁,等待⼀定的时间之后就放弃加锁
• unlock():解锁

ReentrantLock lock = new ReentrantLock();
-----------------------------------------
lock.lock();
try {// working
} finally {lock.unlock()
}

ReentrantLock 的优势:

  1. ReentrantLock ,在加锁的时候,有两种方式
    lock,tryLock(给了更多的可操作空间)
  2. ReentrantLock ,提供了公平锁的实现(默认情况下是非公平锁)
  3. ReentrantLock 提供了更强大的等待通知机制
    搭配了Condition 类,实现等待通知,可以更精确控制唤醒某个指定的线程

虽然 ReentrantLock 有上述优势,但是在加锁的时候,首选还是 synchronized
但是很明显,ReentrantLock 使用更复杂,尤其容易忘记解锁

3. 信号量

信号量也是操作系统中,比较重要的概念

信号量,就是一个计数器,描述了“可用资源”的个数


举个栗子:
可以把信号量想象成是停⻋场的展⽰牌:
当前有⻋位 100 个,表⽰有 100 个可⽤资源
当有⻋开进去的时候,就相当于申请⼀个可⽤资源,可⽤⻋位就 -1 (这个称为信号量的 P 操作)
当有⻋开出来的时候,就相当于释放⼀个可⽤资源,可⽤⻋位就 +1 (这个称为信号量的 V 操作)
如果计数器的值已经为 0 了,还尝试申请资源,就会阻塞等待,直到有其他线程释放资源


英语中 P 操作 用 acquire
V 操作 用 release


锁,本质上就是属于一种特殊的信号量
锁就是 可用资源为 1 的信号量
加锁操作,P 操作,1 变成 0
解锁操作,V 操作,0 变成 1
这其实就是二元信号量


操作刺痛,提供了 信号量 实现,提供了 api,JVM 封装了这样的 api,就可以在 java 代码中使用了

public class ThreadDemo36 {public static void main(String[] args) throws InterruptedException {Semaphore semaphore = new Semaphore(4);semaphore.acquire();System.out.println("P 操作");semaphore.acquire();System.out.println("P 操作");semaphore.acquire();System.out.println("P 操作");semaphore.acquire();System.out.println("P 操作");semaphore.acquire();System.out.println("P 操作");//semaphore.release();}
}

在这里插入图片描述
这里第五次操作会堵塞

开发中如果遇到了需要申请资源的常见,就可以使用信号量来实现

4. CountDownLatch

CountDownLatch 主要是适用于,多个线程来完成一系列任务的时候,用来衡量任务的进程是否完成
比如把一个大的任务,拆分成多个小的任务,让这些任务并发的去执行

就可以使用 CountDownLatch 来判定说当前这些任务是否都完成了


下载一个文件,就可以使用多线程下载
在我们的生活中,很多下载工具的下载速度很慢
相比之下,有一些专业的下载工具,就可以成倍的提升(比如 IDM)

这个时候普通的下载软件,往往和资源服务器,只有一个链接,服务器往往会对于链接传输的速度有限制
而专业的软件,往往是多线程下载,每个线程都建立一个链接,此时就需要把任务进行分割


CountDownLatch 主要有两个方法:

  1. await ,调用的时候就会阻塞,就会等待其他的线程完成任务,所有的线程都完成了任务之后,此时这个 await 才会返回,才会继续往下走
  2. countDown ,告诉 CountDownLatch ,我当前这一个子任务已经完成
public class ThreadDemo37 {public static void main(String[] args) throws InterruptedException {//10 个选手参赛,await 就会在 10次调用完 countDown 之后才能继续执行CountDownLatch countDownLatch = new CountDownLatch(10);for (int i = 0; i < 10; i++) {int id = i;Thread t = new Thread(() -> {System.out.println("thread " + id);try {Thread.sleep(500);} catch (InterruptedException e) {throw new RuntimeException(e);}//通知说当前的任务执行完毕了countDownLatch.countDown();});t.start();}countDownLatch.await();System.out.println("所有的任务都完成了");}
}

在这里插入图片描述
如果是 i < 9,这里就会进行阻塞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/217320.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BeautifulSoup学习

前期准备&#xff1a; pip install bs4 pip install lxml bs解析器 从上面的表格可以看出&#xff0c;lxml解析器可以解析HTML和XML文档&#xff0c;并且速度快&#xff0c;容错能力强&#xff0c;所有推荐使用它。 节点选择器 获取名称 soup BeautifulSoup(<b class&…

java面试题-SpringMVC工作原理

远离八股文&#xff0c;面试大白话&#xff0c;通俗且易懂 看完后试着用自己的话复述出来。有问题请指出&#xff0c;有需要帮助理解的或者遇到的真实面试题不知道怎么总结的也请评论中写出来&#xff0c;大家一起解决。 java面试题汇总-目录-持续更新中 这个面试题前几年Sprin…

计算机毕业设计 基于SpringBoot的乡村政务办公系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

持续集成交付CICD:Jenkins流水线操作Harbor仓库

目录 一、实验 1.Jenkins主节点安装Docker 2.Jenkins主节点安装Harbor 3.Jenkins从节点安装Docker 4.Jenkins流水线操作Harbor仓库 二、问题 1.Jenkins主节点登录Harbor仓库报错 2.Jenkins流水线里从节点操作docker报错 3.Jenkins流水线里从节点远程登录Harbor仓库报错…

thinkphp 使用array_reduce 处理返回的数据格式

我想要的效果&#xff1a; 不使用array_reduce 的效果 &#xff1a; 代码&#xff1a; public function teamList($userId,$good_id){$nowbuyers $this->order->where(good_id,$good_id)->count();$data GroupTotalOrder::alias(t_order)->where(merchant_Id,$u…

Jmeter性能测试:ForEach控制器的用法解析(含视频讲解)

引言 最近我在进行JMeter性能测试时遇到了一些问题&#xff0c;特别是在使用ForEach控制器时感到有点棘手。 但是经过不断地摸索和实践&#xff0c;终于成功地掌握了这个神奇的工具&#xff0c;提高了我的测试效率。因此&#xff0c;今天我想和大家分享我的经验&#xff0c;让…

ssh配置学习,ssh连接不上解决方法

ssh 配置学习 文章目录 ssh 配置学习一、基本概念二、ssh常用配置三、ssh常用命令1、指定端口号连接远程主机2、传输文件到远程主机3、sftp 命令用于和远程主机进行文件传输 四、关于ssh现场问题的处理总结 一、基本概念 ssh全称为Secure Shell 简称&#xff0c;是一种加密传输…

产品入门第二讲:Axure产品元件库的使用

&#x1f4da;&#x1f4da; &#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​​​​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Axure》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是…

聊聊AsyncHttpClient的RequestFilter

序 本文主要研究一下AsyncHttpClient的RequestFilter RequestFilter org/asynchttpclient/filter/RequestFilter.java /*** A Filter interface that gets invoked before making an actual request.*/ public interface RequestFilter {/*** An {link org.asynchttpclient…

HTML 字体样式

目录 使用属性样式使用 CSS 样式表HTML 中常用的字体样式属性总结 HTML 是一种用于创建网页的标记语言&#xff0c;开发者可以通过 HTML 编写网页结构和内容。在 HTML 中&#xff0c;字体样式是非常重要的&#xff0c;可以通过设置字体大小、字体颜色、字体样式等方式来让网页内…

力扣322. 零钱兑换

动态规划 思路&#xff1a; 假设 dp[i] 表示金额 i 的零钱兑换最小数量&#xff1b;它可以由 dp[i - C(j)] 1&#xff0c;即由币值C(j) 与 dp[i - C(j)] 组成&#xff0c;要使得数量最少&#xff0c;则 dp[i - C(j)] 最小&#xff1b;边界条件 dp[0] 0&#xff1b;自下而上分…

Android View闪烁动画AlphaAnimation,Kotlin

Android View闪烁动画AlphaAnimation&#xff0c;Kotlin private fun flickerAnimation(view: View?) {val animation: Animation AlphaAnimation(1f, 0f) //不透明到透明。animation.duration 500 // 1次过程时长。animation.interpolator LinearInterpolator() // 线性速…

Axure电商产品移动端交互原型,移动端高保真Axure原型图(RP源文件手机app界面UI设计模板)

本作品是一套 Axure8 高保真移动端电商APP产品原型模板&#xff0c;包含了用户中心、会员成长、优惠券、积分、互动社区、运营推广、内容推荐、商品展示、订单流程、订单管理、售后及服务等完整的电商体系功能架构和业务流程。 本模板由一百三十多个界面上千个交互元件及事件组…

android项目实战之编辑器图片上传预览

现状分析 项目的需求用到编辑器&#xff0c;编辑器中又可能用到图片上传功能。 实现方案 1. 增加依赖库&#xff0c;可以参考前面的几篇文章&#xff0c;都有描述。 2. 核心代码实现 PictureSelector.create(GoodItemContentFragment.this) .openGallery(SelectMimeType.…

如何在上架App之前设置证书并上传应用

App上架教程 在上架App之前想要进行真机测试的同学&#xff0c;请查看《iOS- 最全的真机测试教程》&#xff0c;里面包含如何让多台电脑同时上架App和真机调试。 P12文件的使用详解 注意&#xff1a; 同样可以在Build Setting 的sign中设置证书&#xff0c;但是有点麻烦&…

Python查找列表中不重复的数字

Python每日一练 文章目录 Python每日一练问题&#xff1a;函数输入函数输出 代码实现示例输入&#xff1a;示例输出&#xff1a; 总结 问题&#xff1a; 编写一个程序来查找列表中不重复的数字。 定义函数find_unique()&#xff0c;它接受一个列表作为参数。 在函数内部&…

Log4j.xml配置说明

介绍 Log4j 2 是一款广泛使用的 Java 日志框架&#xff0c;它支持多种日志级别、异步日志、过滤器等功能&#xff0c;并且具有高性能和可扩展性。以下是 Log4j 2 的详细配置说明&#xff1a; 配置文件名称和存放位置&#xff1a;Log4j 2 的配置文件名可以是任意有效的文件名&a…

微信小程序:上传图片到别的域名文件下

效果 wxml <!-- 上传照片 --> <view class"addbtn"><view classpic name"fault_photo" wx:for"{{imgs}}" wx:for-item"item" wx:key"*this"><image classweui-uploader_img src"{{item}}"…

Kafka-客户端使用

理解Kafka正确使用方式 Kafka提供了两套客户端API&#xff0c;HighLevel API和LowLevel API。 HighLevel API封装了kafka的运行细节&#xff0c;使用起来比较简单&#xff0c;是企业开发过程中最常用的客户端API。 LowLevel API则需要客户端自己管理Kafka的运行细节&#xf…

使用spring-boot-devtools时可能会引起缓存实体转换异常

多次访问API接口时&#xff0c;会报底层实体转换异常排查&#xff0c; 排查自己写的代码&#xff0c;及使用的框架&#xff0c; 最终发现是引用了 热部署插件引起&#xff0c;关闭了插件无影响&#xff1b; 使用spring-boot-devtools时&#xff0c;需要注意这个问题了。 <…