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就可以看到多了…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
