多线程之基础篇(一)

一、Thread类

1、线程的创建 

大家都熟知创建单个线程的三种方式,通过继承Thread类创建线程并重写该类的run()方法;通过实现Runnable接口创建线程一样要重写run()方法;以上的两个run()方法都是线程的执行体;第三,使用Callable和Future来创建线程Callable接口提供了一个call()方法来作为线程的执行体,call()方法比run()方法功能要更加强大,call()方法可以有返回值,call()方法可以声明抛出异常(前两种如果要抛异常只能通过try,catch来实现);下面详细介绍一下Callable和Future

我们知道创建线程最终要由操作系统支持,java中只有调掉Thread对象,最后执行一个叫private native void start0();的本地方法,而该方法的最终实现在C++和C层面,要阅读JVM源码才能更深一步,暂时咱们知道最后是由操作系统给我们另起了一个线程取执行 “执行体”里面的业务。我们看Thread类的构造方法里面没有直接传Callable接口的构造方法,那为啥我们还能运行下面这段代码呢?

    /*** Callable需要配合FutureTask使用* FutureTask的get()可以返回任务的执行结果,方便在2个线程之间,把一个线程的结果传给另一个线程** @throws InterruptedException* @throws ExecutionException*/private static void testFutureAndCallable() throws InterruptedException, ExecutionException {FutureTask<Integer> future = new FutureTask<>(() -> {log.debug("running.....");Thread.sleep(1000);return 100;});Thread t3 = new Thread(future, "t3");t3.start();// 当主线程运行到get方法时,主线程会阻塞住,一直等待 t1线程 结果返回log.debug("main接收future的返回值:{}",future.get());log.debug("main线程继续运行....");}

我们可以看到,直接把future对象传入给了Thread构造方法,其实我们可以从FureTask出发, FutureTask实现了RunnableFuture接口,而RunnableFuture又同时实现了Runnable和Future接口,所以在直接构造Thread时可以直接传入构造参数执行。

public class FutureTask<V> implements RunnableFuture<V> {}public interface RunnableFuture<V> extends Runnable, Future<V> {}

尽管FureTask+Callable有返回值,可以抛异常,可以查看线程执行任务的情况,但是有时候为获取它的返回值主线程而陷入阻塞等待,另一个isDone()方法轮询获取值容易耗CPU资源.........

针对以上2个痛点JDK做了扩展CompletableFuture类同时实现了Future和CompletionStage接口,在CompletionStage上做了极大的扩展

Runnable——没有输入参数,也没有返回值

Function——功能型函数接口,有一个参数,有一个返回参数

Consumer——消费型函数接口,有一个输入参数,没有返回参数

—Consumer延申BiConsumer,有两个输入参数,没有返回参数

Supplier——供给型函数接口,没有输入参数,有返回值

数式接口名称方法名称参数返回值
Runnablerun无参数无返回值
Functionapply1个参数有返回值
Consumeraccept1个参数无返回值
Supplierget无参数有返回值
BiConsumeraccept2个参数

无返回值

2、interrupt()、interrupted()、isinterrupted()  

public void interrupt()

实例方法

,Just to set the interrupt flag

实例方法interrupt()仅仅是设置线程的中断状态为true,发起一个协商而不会立刻停止线程。

如果线程处于被阻塞状态(例如处于sleep,wait,join等状态),在别的线程中调用当前线程对象的interrupt方法,那么线程将立即退出被阻塞状态,并抛出一个InterruptException异常。

public static boolean interrupted()

静态方法,Thread.interrupted();

判断线程是否被中断并清除当前中断状态。

这个方法做了两件事

1.返回到当前线程的中断状态,测试当前线程是否已被中断。

2.将当前线程的中断状态清零并重新设为false,清除线程的中断状态

public boolean isInterrupted()

实例方法

判断当前线程是否被中断(通过检查中断标志位)

二、Java的锁  

乐观锁:

        1、版本号version

        2、CAS(compareAndSwap)算法,java原子类(Atomic打头的类)中的递增操作就是通过CAS自旋实现的。——Unsafe类

使用场景:适合读操作多的场景,不加锁的特点能够使其读取操作的性能大幅提升。乐观锁则直接去操作同步资源,是一种无锁算法

悲观锁: 同一时间点有且仅有一个线程占有锁

        1、synchronized

        2、ReentrantLock

使用场景:适合写操作多的场景,先加锁可以保证写操作时数据正确,现实的锁定之后在操作同步资源 

1、synchronized

 为什么任何一个对象都可以成为一把锁?

因为Java中所有的对象都默认继承了超类Object,而Object在JVM源码(C++)层面关联了一个对象ObjectMonitor,所以每个对象“天生”都带着一个对象监视器,也就是每一个被锁住的对象都会和Monitor关联起来。

 ObjectMonitor中有几个关键属性

_owner指向持有ObjectMonitor对象的线程
_WaitSet存放于wait状态的线程队列
_EntryList存放处于等待锁block状态的线程队列
_recursious锁的重入次数
_count用来记录该线程获取锁的次数

管程:Monitors,也叫监视器

是一种程序结构,结构内的多个子程序(对象或模块)形成的多个工作线程互斥访问共享资源。这些共享资源一般是硬件设备或一群变量。对共享变量能够进行的所有操作集中在一个模块中。(把信号量及其操作原语“封装”在一个对象内部)管程实现了在一个时间点,最多只有一个线程在执行管程的某个子程序。管程提供了一种机制,管程可以看作一个软件模块,它是将共享的变量和对于这些共享变量的操作封装起来,形成一个具有一定接口的功能模块,进程可以调用管程来实现进程级别的并发控制。

注:synchronized和 static synchronized前者是对象锁,后者是类锁,属于不同的锁,a线程加对象锁,b线程加类锁,加锁不同,a、b线程不会产生竟态条件。

 2、自旋锁

没有成员变量的类一般都是线程安全的

cynchronized

 

 

并发压测工具 

 

 装饰器模式:Collections以synchronized打头的的实现集合的那些方法就是采用了装饰器模式。

1、AQS

AQS全称是AbstractQueuedSynchronizer,是阻塞式锁和相关的同步器工具的框架

特点:

1、用state属性来表示资源的状态(分独占模式和共享模式),子类需要定义如何维护这个状态,控制如何获取锁和释放锁

—getState-获取state状态

—setState-设置state状态

—compareAndSetState-cas机制设置state状态[compare式保证state的原子性]

2、提供了基于FIFO的等待队列,类似于Monitor的EntryList

3、条件变量来实现等待、唤醒机制,支持多个条件变量,类似于Montor的WaitSet

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

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

相关文章

组件安全以及漏洞复现

组件安全 1. 概述 A9:2017-使⽤含有已知漏洞的组件 A06:2021-Vulnerable and Outdated Components ​ 组件&#xff08;例如&#xff1a;库、框架和其他软件模块&#xff09;拥有和应用程序相同的权限。如果应用程序中含有已知漏洞的组件被攻击者利用&#xff0c;可能会造成…

目标检测入门

一、目标检测任务对比 二、目标检测发展路线 基于深度学习的目标检测大致可以分为一阶段(One Stage)模型和二阶段(Two Stage)模型。目标检测的一阶段模型是指没有独立地提取候选区域(Region Proposal)&#xff0c;直接输入图像得到图中存在的物体类别和相应的位置信息。典型的一…

.net 7 隐藏swagger的api

1.写一个隐藏接口特性表示 using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen;using System.Web.Http.Description;namespace JiaTongInterface.Filter {public class SwaggerApi : Swashbuckle.AspNet…

iframe 实现跨域,两页面之间的通信

一、 背景 一个项目为vue2&#xff0c;一个项目为vue3&#xff0c;两个不同的项目实现iframe嵌入&#xff0c;并实现通信 二、方案 iframe跨域时&#xff0c;iframe组件之间常用的通信&#xff0c;主要是H5的possmessage方法 三、案例代码 父页面-vue2&#xff08;端口号为…

“投资教父”熊晓鸽老了,IDG光环不再

作者 | 鸠白 艺馨 排版 | Cathy 监制 | Yoda 出品 | 不二研究 2017年&#xff0c;世界互联网大会上&#xff0c;“投资教父”熊晓鸽问映客的创始人&#xff1a;“今年你们利润能有多少&#xff1f;” 对方笑答&#xff1a;“5个亿吧&#xff01;” “才五个亿&#xff1f…

Kubernetes (K8s) 解读:微服务与容器编排的未来

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f6e0;️ 全栈技术 Full Stack: &#x1f4da…

leetcode 234. 回文链表

2023.9.5 本题先将链表的节点值移到数组中&#xff0c;再用双指针去判断该数组是否为回文的即可。 代码如下&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* …

细说GNSS模拟器的RTK功能(三)应用实例01——运行和分析模拟

在上期文章中我们介绍了基于RTCM插件来模拟RTCM使用的硬件和软件设置&#xff0c;本期文章我们将继续进行运行和分析模拟。 使用RTCM插件 运行和分析模拟 连接Ublox接收器 虽然采用了Novatel接收器进行模拟来获得更好的位置精度&#xff0c;但也同样适用于Ublox接收器。要将…

【数据结构】前言概况 - 树

&#x1f6a9;纸上得来终觉浅&#xff0c; 绝知此事要躬行。 &#x1f31f;主页&#xff1a;June-Frost &#x1f680;专栏&#xff1a;数据结构 &#x1f525;该文章针对树形结构作出前言&#xff0c;以保证可以对树初步认知。 目录&#xff1a; &#x1f30d;前言:&#x1f3…

Pytorch Advanced(三) Neural Style Transfer

神经风格迁移在之前的博客中已经用keras实现过了&#xff0c;比较复杂&#xff0c;keras版本。 这里用pytorch重新实现一次&#xff0c;原理图如下&#xff1a; from __future__ import division from torchvision import models from torchvision import transforms from PIL…

Json“牵手”亚马逊商品详情数据方法,亚马逊商品详情API接口,亚马逊API申请指南

亚马逊平台是美国最大的一家网络电子商务公司&#xff0c;亚马逊公司是1995年成立&#xff0c;刚开始只做网上书籍售卖业务&#xff0c;后来扩展到了其他产品。现在已经是全世界商品品种最多的网上零售商和第二互联网公司&#xff0c;亚马逊是北美洲、欧洲等地区的主流购物平台…

数据结构:线性表之-循环双向链表(万字详解)

目录 基本概念 1&#xff0c;什么是双向链表 2&#xff0c;与单向链表的区别 双向链表详解 功能展示&#xff1a; 1. 定义链表 2&#xff0c;创建双向链表 3&#xff0c;初始化链表 4,尾插 5&#xff0c;头插 6&#xff0c;尾删 判断链表是否被删空 尾删代码 7&a…

我们这一代人的机会是什么?

大家好&#xff0c;我是苍何&#xff0c;今天作为专业嘉宾参观了 2023 年中国国际智能产业博览会&#xff08;智博会&#xff09;&#xff0c;是一场以「智汇八方&#xff0c;博采众长」为主题的汇聚全球智能技术和产业创新的盛会&#xff0c;感触颇深&#xff0c;随着中国商业…

9月11日作业

思维导图 代码 #include <iostream> #include<string.h>using namespace std;class myString { private:char *str; //记录c风格的字符串int size; //记录字符串的实际长度 public://无参构造myString():size(10){str new char[size]; …

淘宝京东扣库存怎么实现的

1. 使用kv存储实时的库存&#xff0c;直接在kv里扣减&#xff0c;避免用分布式锁 2. 不要先查再扣&#xff0c;直接扣扣扣&#xff0c;扣到负数&#xff0c;&#xff08;增改就直接在kv里做&#xff09;&#xff0c;就说明超卖了&#xff0c;回滚刚才的扣减 3. 同时写MQ&…

JVM类加载机制

目录 一、Java为什么是一种跨平台的语言&#xff1f; 二、Java代码的执行流程 解释执行为主&#xff0c;编译执行为辅&#xff1a; 三、类加载的过程 3.1、加载 类加载器&#xff08;就是加载类的&#xff09;分为&#xff1a; 3.1.1、启动类加载器&#xff08;Bootstrap…

UMA 2 - Unity Multipurpose Avatar☀️三.给UMA设置默认服饰Recipes

文章目录 🟥 项目基础配置🟧 给UMA配置默认服饰Recipes🟨 设置服饰Recipes属性🟥 项目基础配置 将 UMA_DCS 预制体放到场景中创建空物体,添加DynamicCharacterAvatar 脚本,选择 HumanMaleDCS作为我们的基本模型配置默认Animator 🟧 给UMA配置默认服饰Recipes 服饰Re…

回归预测 | MATLAB实现PCA-BP主成分降维结合BP神经网络多输入单输出回归预测

回归预测 | MATLAB实现PCA-BP主成分降维结合BP神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现PCA-BP主成分降维结合BP神经网络多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 MATLAB实现PCA-BP主成分降维算法结合BP神经网络多输入单输出回…

【数据结构】串

串 串的顺序实现简单的模式匹配算法KMP算法KMP算法的进一步优化 串的顺序实现 初始化 #define MaxSize 50 typedef char ElemType;//顺序存储表示 typedef struct{ElemType data[MaxSize];int length; }SString;/*** 初始化串*/ void InitString(SString *string) {for (int …

Cmake入门(一文读懂)

目录 1、Cmake简介2、安装CMake3、CMakeLists.txt4、单目录简单实例4.1、CMakeLists.txt4.2、构建bulid内部构建外部构建 4.3、运行C语言程序 5、多目录文件简单实例5.1、根目录CMakeLists.txt5.2、源文件目录5.3、utils.h5.4、创建build 6、生成库文件和链接外部库文件7、注意…