JAVA基础学习笔记_多线程
文章目录
- 多线程
- 并发和并行
- 多线程的实现方式
- Thread类实现
- Runnable接口方式实现
- callable接口和Future接口实现
- 常用的成员方法
- 线程的生命周期
- 线程的安全问题
- 同步代码块
- 同步方法
- lock锁
- 死锁
- 生产者和消费者(等待唤醒机制)
- 阻塞队列实现等待唤醒机制
- 线程的6种状态
- 线程池
- 自定义线程池
- 最大并行数
- 线程池合适的大小
- 多线程的额外扩展
多线程
线程是操作系统能够运算调度的最小单位,被包含在进程之中
就是让程序做多件事情
并发和并行
并发,在同一时刻,有多个指令在单个CPU上交替执行
并行,在同一时刻,多个指令在多个CPU上同时执行
多线程的实现方式
Thread类实现
public class MyThread extends Thread{@Overridepublic void run(){for(int i= 0;i<100;i++){System.out.println(getName()+"hello");}}
}
//自己定义一个类继承thread
//重写run方法
//创建子类的对象,启动线程
public static void main(String[] args) {MyThread t1 = new MyThread();MyThread t2 = new MyThread();t1.setName("线程1");t2.setName("线程2");t1.start();t2.start();
}
Runnable接口方式实现
接口的意义,java是单继承方式的,所以为了扩展性和灵活性有个接口
public class MyRun implements Runnable{@Overridepublic void run() {for(int i= 0;i<100;i++){//调用当前线程的静态方法,获取当前线程对象Thread t = Thread.currentThread();System.out.println(t.getName()+"hello");//或者用链式编程写成以下System.out.println(Thread.currentThread().getName()+"hello");}}
}
public static void main(String[] args) {MyRun mr = new MyRun();Thread t1 = new Thread(mr);Thread t2 = new Thread(mr);t1.setName("线程1");t2.setName("线程2");t1.start();t2.start();
}
callable接口和Future接口实现
public class Mycallable implements Callable<Integer> {//前面两种方式不能返回线程的结果,但这个可以@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 0; i < 100; i++) {sum = sum+i;}return sum;}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {Mycallable mc = new Mycallable();//用FutureTask对象管理运行结果FutureTask<Integer> ft = new FutureTask<>(mc);Thread t1= new Thread();t1.start();Integer result = ft.get();System.out.println(result);
}
常用的成员方法
getName()//返回线程的名称,在main方法中不指定是那个线程,这个线程的名字就是main线程,跟linux系统编程一样,同属一个祖宗
setName()//设置线程的名字
static Thread currentThread()//获取当前线程的对象
static void sleep();设置休眠时间
//优先级方法,抢占式调度,优先级越高,抢到cpu概率是越大的,只是概率大
setPriority()//设置线程的优先级
getPriority()//获得线程优先级
//守护线程,当其他的非守护线程执行完毕,守护线程会陆续结束,没有存在的必要了
//比如聊天窗口线程结束,那么传输文件的线程也就没必要存在了
setDaemon()//设置为守护线程
//礼让线程
yield()//出让当前CPU的执行权
//插入线程
t.join()//把t线程插入到当前线程之前
线程的生命周期
- 新建,创建线程
- 就绪,有执行资格没有执行权
- 运行,有执行资格有执行权
- 阻塞,没有执行资格没有执行权
- 死亡,线程死亡变成垃圾
线程的安全问题
线程执行时,有随机性
同步代码块
锁就是大门钥匙,谁拿到了,谁就可以进到对应的程序里面
//三个窗口买票,共卖一百张票
public class MyThread extends Thread{static int ticket = 0;static Object obj = new Object();public void run(){while(true){//同步代码块//锁,就类似于sql的事务synchronized (obj){if(ticket<100){try{Thread.sleep(10);}catch(InterruptedException e){e.printStackTrace();}ticket++;System.out.println(getName()+"正在卖第"+ticket+"张票");}}}}
}
同步方法
private synchronized boolean extracted()
- 同步方法是锁方法里面所有的代码
- 锁对象不能自己指定,如果是非静态方法,this,如果是静态方法是当前的字节码文件
public class MyRun implements Runnable{int ticket = 0;@Overridepublic void run() {while(true){if (extracted()) break;}}private synchronized boolean extracted() {if (ticket == 100) {return true;} else{try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}ticket++;System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket + "张票");}return false;}
}
lock锁
手动加锁和释放
public class MyThread extends Thread{static int ticket = 0;static Lock lock = new ReentrantLock();//Lock是接口,要新建实现类@Overridepublic void run() {while (true){lock.lock();;try{if(ticket ==100){break;}else{Thread.sleep(10);ticket++;System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");}}catch (Exception e){e.printStackTrace();}finally {//finally,无论有无异常,这里的代码都会执行lock.unlock();}}}
}
死锁
线程A占着A锁,线程B拿着B锁,但是两个线程此时想访问对方的锁,就死锁了
生产者和消费者(等待唤醒机制)
线程的执行具有随机性,所以等待唤醒机制可以让执行均匀
比如,桌子上有食物,消费者(线程A)开吃,桌子没有食物,厨师(线程B)开做
执行代码
public static void main(String[] args) throws ExecutionException, InterruptedException {Cook c= new Cook();Foodie f = new Foodie();c.setName("厨师");f.setName("吃货");c.start();f.start();
}
厨师逻辑
public class Cook extends Thread {public void run() {while (true) {synchronized (Desk.lock) {if (Desk.count == 0) {break;} else {if (Desk.foodFlag == 1) {try {Desk.lock.wait();} catch (InterruptedException e) {e.printStackTrace();}} else {System.out.println("厨师正在做第" + Desk.count + "个汉堡");Desk.foodFlag = 1;Desk.lock.notifyAll();}}}}}
}
吃货逻辑
public class Foodie extends Thread{public void run(){while(true){synchronized (Desk.lock){if(Desk.count==0){break;}else{if (Desk.foodFlag==0) {try {Desk.lock.wait();//释放当前锁对象,直到有人唤醒} catch (InterruptedException e) {e.printStackTrace();}} else {Desk.count--;System.out.println("吃货正在吃第"+Desk.count+"个汉堡");Desk.lock.notifyAll();//唤醒所有线程Desk.foodFlag=0;}}}}}
}
桌子逻辑
/*** 控制生产者和消费者的执行*/
public class Desk {//0,没有面条,1,有面条public static int foodFlag = 0;//总个数public static int count = 10;//锁对象public static Object lock = new Object();
}
阻塞队列实现等待唤醒机制
队列机制,两个线程在一个队列中取和存数据
线程的6种状态
并没有运行状态,为了好理解,可以虚拟出这么一个状态
- 新建
- 就绪
- 阻塞
- 等待wait(),无执行资格无执行权
- 计时sleep(),无执行资格无执行权
- 结束
线程池
- 提交任务时,池子会创建新的线程,执行完毕后,线程归还给池子,再提交任务是,不需要创建新的线程,用已有的线程
- 提交任务没有空闲线程,也无法创建新线程,任务排队等待
public static void main(String[] args) throws ExecutionException, InterruptedException {//Executors.newCachedThreadPool()//无限线程池//Executors.newFixedThreadPool()//有上限的线程池//创建线程池对象ExecutorService pool1 = Executors.newFixedThreadPool(3);//提交任务pool1.submit(new MyRun());pool1.submit(new MyRun());pool1.submit(new MyRun());pool1.submit(new MyRun());pool1.submit(new MyRun());
}
自定义线程池
- 当核心线程满时,再提交会排队
- 当核心线程满,队伍满时,会创建临时线程
- 当核心线程满,队伍满,临时线程满时,会触发任务拒绝策略
public static void main(String[] args) {new ThreadPoolExecutor(3,//核心线程数6,//最大线程数60,//存活时间TimeUnit.SECONDS,//存活时间时间单位new ArrayBlockingQueue<>(3),//阻塞队列长度Executors.defaultThreadFactory(),//线程工厂new ThreadPoolExecutor.DiscardPolicy()//拒绝策略);
}
最大并行数
我的电脑是32核32线程最大并行,超线程技术可以64线程,是因为实现让1个核分身同时为两个线程服务
线程池合适的大小
CPU密集型运算,最大并行数+1
I/O密集型运算,最大并行数期望CPU利用率((CPU计算时间+等待时间)/CPU计算时间)
多线程的额外扩展
- volatile
- jMM
- 悲观锁\乐观锁\CAS
- 原子性
- 并发工具类
相关文章:
JAVA基础学习笔记_多线程
文章目录 多线程并发和并行多线程的实现方式Thread类实现Runnable接口方式实现callable接口和Future接口实现 常用的成员方法线程的生命周期线程的安全问题同步代码块同步方法lock锁死锁 生产者和消费者(等待唤醒机制)阻塞队列实现等待唤醒机制线程的6种状态线程池自定义线程池…...
什么是自动化办公
自动化办公是指使用技术工具或软件,通过预设流程或脚本,自动执行日常办公任务,从而提升效率、减少错误、节约时间的办公模式。它适用于需要重复性、规则明确的工作流程,让员工将精力集中在更具创造性和战略性的工作上。 自动化办公…...
数据库系统
数据库模式 3个阶段以及各自的产物: 1、需求分析(数据流图、数据字典、需求说明书); 2、概念结构设计(ER模型); 3、逻辑结构设计(关系模式)); 关…...
文件系统--底层架构(图文详解)
一、文件系统的底层存储与寻址 当我们谈到文件系统的底层结构时,最关键的问题是:文件的数据与元数据(属性)如何存储在磁盘上,以及系统是如何定位这些数据的?在谈及文件系统之前,我们要先对储存…...
【OCR】——端到端文字识别GOT-OCR2.0不香嘛?
代码:https://github.com/Ucas-HaoranWei/GOT-OCR2.0?tabreadme-ov-file 在线demo:https://huggingface.co/spaces/stepfun-ai/GOT_official_online_demo 0.前言 最早做ocr的时候,就在想如何能做一个端到端的模型,就不用先检测再…...
SkyWalking 和 ELK 链路追踪实战
一、背景 最近在给项目搭建日志平台的时候,采用的方案是 SkyWalking ELK 日志平台,但发现 ELK 日志平台中的日志没有 Trace ID,导致无法追踪代码报错的整体链路。 空哥提示:Trace ID 是分布式追踪中用来唯一标识一个服务请求或事…...
ETCD的封装和测试
etcd是存储键值数据的服务器 客户端通过长连接watch实时更新数据 场景: 当主机A给服务器存储 name: 小王 主机B从服务器中查name ,得到name-小王 当主机A更改name 小李 服务器实时通知主机B name 已经被更改成小李了。 应用:服务注册与发…...
基于大数据爬+数据可视化的民族服饰数据分析系统设计和实现(源码+论文+部署讲解等)
博主介绍:CSDN毕设辅导第一人、全网粉丝50W,csdn特邀作者、博客专家、腾讯云社区合作讲师、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围…...
torch.optim.lr_scheduler.ReduceLROnPlateau
torch.optim.lr_scheduler.ReduceLROnPlateau 是 PyTorch 中的一种学习率调度器,主要用于在模型训练过程中根据某些指标(如验证损失)动态调整学习率。它是一种基于性能指标动态调整学习率的策略,而不是预定义的固定时间调整。 主要…...
Linux 搭建ftp服务
FTP是什么? FTP(文件传输协议,File Transfer Protocol)是一种用于在计算机之间传输文件的网络协议。它基于客户端-服务器模型,允许用户从远程服务器上传、下载和管理文件。 FTP的主要作用 文件传输:FTP最基…...
阳光电源嵌入式面试题及参考答案
讲一讲声明变量的时候应该注意哪些内容。 在声明变量时,首先要考虑变量的类型。不同的数据类型有不同的用途和占用的存储空间大小。例如,基本数据类型如整型(int)通常占用 4 个字节,用来存储整数;而浮点型(float)用于存储带有小数部分的数字,占用 4 个字节,双精度浮点…...
PS的功能学习(形状、文字、图层)
关于图层 如果是在一个已经有其他图层的文档界面下,拉一张新图进来,就会自动转换成智能对象 注意,放大之后再栅格化,是会根据原本的防矢量图规则放大之后,再变回像素图层,这个变回来的像素图层是“在原像素…...
项目实例_FashionMNIST_CNN
前言 提醒: 文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。 其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展…...
Ubuntu 安装 web 服务器
安装 apach sudo apt install apache2 -y 查看 apach2 版本号 apache2 -v 检查是否启动服务器 sudo service apache2 status 检查可用的 ufw 防火墙应用程序配置 sudo ufw app list 关闭防火墙 sudo ufw disable 更改允许通过端口流量 sudo ufw allow Apache Full 开启…...
burp的编解码,日志,比较器
声明! 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&a…...
2.1、模版语法
2.1.1、插值语法 1、代码示例 <body><!-- 准备容器 --><div id"app"><!-- 在data中声明的 --><!--1、 data中声明的变量 --><h1>{{msg}}</h1><h1>{{sayHello()}}</h1><!-- 不在data中的变量不可以 -->…...
最小二乘法拟合出二阶响应面近似模型
背景:根据样本试验数据拟合出二阶响应面近似模型(正交二次型),并使用决定系数R和调整的决定系数R_adj来判断二阶响应面模型的拟合精度。 1、样本数据(来源:硕士论文《航空发动机用W形金属密封环密封性能分析…...
【汽车】-- 常见的汽车悬挂系统
汽车悬挂系统是车辆的重要组成部分,其主要功能是连接车轮和车身,减缓路面颠簸对车身的影响,提高行驶的平顺性、舒适性和操控性。以下是常见的汽车悬挂系统类型及其特点: 1. 独立悬挂系统 每个车轮可以独立上下运动,不…...
VMware Workstation Pro 17 下载 以及 安装 Ubuntu 20.04.6 Ubuntu 启用 root 登录
1、个人免费版本 VMware Workstation Pro 17 下载链接怎么找?直接咕咕 VMware 找到如下链接。链接如下:Workstation 和 Fusion 对个人使用完全免费,企业许可转向订阅 - VMware 中文博客 点进去链接之后你会看到如下,注意安装之后仍…...
记录ubuntu22.04重启以后无法获取IP地址的问题处理方案
现象描述:我的虚拟机网络设置为桥接模式,输入ifconfig只显示127.0.0.1,不能连上外网。,且无法上网,用ifconfig只有如下显示: 1、sudo -i切换为root用户 2、输入dhclient -v 再输入ifconfig就可以看到多了…...
linux 删除系统特殊的的用户帐号
禁止所有默认的被操作系统本身启动的且不需要的帐号,当你第一次装上系统时就应该做此检查,Linux提供了各种帐号,你可能不需要,如果你不需要这个帐号,就移走它,你有的帐号越多,就越容易受到攻击。 1.为删除你系统上的用户,用下面的…...
core Webapi jwt 认证
core cookie 验证 Web API Jwt 》》》》用户信息 namespace WebAPI001.Coms {public class Account{public string UserName { get; set; }public string UserPassword { get; set; }public string UserRole { get; set; }} }》》》获取jwt类 using Microsoft.AspNetCore.Mvc…...
【Redis】Redis基础——Redis的安装及启动
一、初识Redis 1. 认识NoSQL 数据结构:对于SQL来说,表是有结构的,如字段约束、字段存储大小等。 关联性:SQL 的关联性体现在两张表之间可以通过外键,将两张表的数据关联查询出完整的数据。 查询方式: 2.…...
Oracle Recovery Tools工具一键解决ORA-00376 ORA-01110故障(文件offline)---惜分飞
客户在win上面迁移数据文件,由于原库非归档,结果导致有两个文件scn不一致,无法打开库,结果他们选择offline文件,然后打开数据库 Wed Dec 04 14:06:04 2024 alter database open Errors in file d:\app\administrator\diag\rdbms\orcl\orcl\trace\orcl_ora_6056.trc: ORA-01113:…...
常用环境部署(二十四)——Docker部署开源物联网平台Thingsboard
1、Docker和Docker-compose安装 参考网址如下: CENTOS8.0安装DOCKER&DOCKER-COMPOSE以及常见报错解决_centos8安装docker-compose-CSDN博客 2、 Thingsboard安装 (1)在/home目录下创建docker-compose.yml文件 vim /home/docker-com…...
SqlServer Doris Flink SQL 类型映射关系
SqlServer 对应 Flink SQL 数据类型映射关系 SQL Server TypeFlink SQL Typechar(n)CHAR(n)varchar(n)VARCHAR(n)nvarchar(n)VARCHAR(n)nchar(n)VARCHAR(n)textSTRINGntextSTRINGxmlSTRINGdecimal(p, s)DECIMAL(p, s)moneyDECIMAL(p, s)smallmoneyDECIMAL(p, s)numericNUMERIC…...
Java 中的方法重写
在 Java 中,方法重写(Method Overriding)是面向对象编程的一个重要概念,它指的是子类中存在一个与父类中相同名称、相同参数列表和相同返回类型的方法。方法重写使得子类可以提供特定的实现,从而覆盖(或改变…...
v-for遍历多个el-popover;el-popover通过visible控制显隐;点击其他隐藏el-popover
场景:el-popover通过visible控制显隐;同时el-popover是遍历生成的多个。 原文档的使用visible后就不能点击其他地方使其隐藏;同时解决实现点击其他区域隐藏 <template><div><template v-for="(item,index) in arr" :key="index"><…...
从 Excel 文件中读取数据生成 SQL 语句[快捷main方法]
从 Excel 文件中读取数据生成 SQL 语句的实现 在日常工作中,我们经常需要从 Excel 文件中提取数据,并将其转换为 SQL 插入语句,以便于将数据导入到数据库中。在这篇文章中,我将展示如何使用 Java 来实现这一需求。 项目需求 我…...
从0到1实现项目Docker编排部署
在深入讨论 Docker 编排之前,首先让我们了解一下 Docker 技术本身。Docker 是一个开源平台,旨在帮助开发者自动化应用程序的部署、扩展和管理。自 2013 年推出以来,Docker 迅速发展成为现代软件开发和运维领域不可或缺的重要工具。 Docker 采…...
做公司网站建设价格/合肥关键词排名技巧
1, 数据 函数程序 都定义在 实例化对象中通过调用 实例化对象的函数方法 调用 实例化对象中 存储的数据执行程序 实现效果2, this指向必须是实例化对象匿名函数 --- 箭头函数回调函数 通过 bind() 语法修改设定 this指向提前定义一个变量 存储this指向一个函数中 要是用 多个…...
温州手机网站建设/网络营销渠道可分为
os 模块: 和操作系统打交道的模块 os模块是与操作系统交互的一个接口 os.makedirs(dirname1/dirname2) 可生成多层递归目录 os.removedirs(dirname1) 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除&a…...
安卓开发app/贵港网站seo
...
做网站都需要数据库吗/民宿平台搜索量上涨
编辑:哈雷 | 来源:巨盒创意 | 欢迎转发到朋友圈 日常工作中,我们可能有这样的需求,我们的数据分别存放在N个工作簿里,我们需要把这些零散的数据都移动到一个工作簿里面,而且每张工作表分别存在…...
免费响应式网站/排名优化公司哪家靠谱
有不少使用Python语言编写策略的开发者希望把策略代码文件放在本地,担心策略安全性。正如FMZ API文档中提出的一种方案: 策略安全性 在发明者量化交易平台上开发策略,策略仅发明者量化账户持有者可见。并且在发明者量化交易平台上可以实现策略…...
甘露园网站建设/百度推广最近怎么了
saltstack使用jinja2增加了pillar模块pillar功能是帮助用户自定义一些变量,对于书写state file带来很大便利,同时增加了任务的隐藏性使用方法:在state file根目录同级目录建立pillar目录,书写sls配置文件pillar同样适用yaml格式,只…...