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

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种状态线程池自定义线程池…...

什么是自动化办公

自动化办公是指使用技术工具或软件&#xff0c;通过预设流程或脚本&#xff0c;自动执行日常办公任务&#xff0c;从而提升效率、减少错误、节约时间的办公模式。它适用于需要重复性、规则明确的工作流程&#xff0c;让员工将精力集中在更具创造性和战略性的工作上。 自动化办公…...

数据库系统

数据库模式 3个阶段以及各自的产物&#xff1a; 1、需求分析&#xff08;数据流图、数据字典、需求说明书&#xff09;&#xff1b; 2、概念结构设计&#xff08;ER模型&#xff09;&#xff1b; 3、逻辑结构设计&#xff08;关系模式&#xff09;&#xff09;&#xff1b; 关…...

文件系统--底层架构(图文详解)

一、文件系统的底层存储与寻址 当我们谈到文件系统的底层结构时&#xff0c;最关键的问题是&#xff1a;文件的数据与元数据&#xff08;属性&#xff09;如何存储在磁盘上&#xff0c;以及系统是如何定位这些数据的&#xff1f;在谈及文件系统之前&#xff0c;我们要先对储存…...

【OCR】——端到端文字识别GOT-OCR2.0不香嘛?

代码&#xff1a;https://github.com/Ucas-HaoranWei/GOT-OCR2.0?tabreadme-ov-file 在线demo&#xff1a;https://huggingface.co/spaces/stepfun-ai/GOT_official_online_demo 0.前言 最早做ocr的时候&#xff0c;就在想如何能做一个端到端的模型&#xff0c;就不用先检测再…...

SkyWalking 和 ELK 链路追踪实战

一、背景 最近在给项目搭建日志平台的时候&#xff0c;采用的方案是 SkyWalking ELK 日志平台&#xff0c;但发现 ELK 日志平台中的日志没有 Trace ID&#xff0c;导致无法追踪代码报错的整体链路。 空哥提示&#xff1a;Trace ID 是分布式追踪中用来唯一标识一个服务请求或事…...

ETCD的封装和测试

etcd是存储键值数据的服务器 客户端通过长连接watch实时更新数据 场景&#xff1a; 当主机A给服务器存储 name&#xff1a; 小王 主机B从服务器中查name ,得到name-小王 当主机A更改name 小李 服务器实时通知主机B name 已经被更改成小李了。 应用&#xff1a;服务注册与发…...

基于大数据爬+数据可视化的民族服饰数据分析系统设计和实现(源码+论文+部署讲解等)

博主介绍&#xff1a;CSDN毕设辅导第一人、全网粉丝50W,csdn特邀作者、博客专家、腾讯云社区合作讲师、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围…...

torch.optim.lr_scheduler.ReduceLROnPlateau

torch.optim.lr_scheduler.ReduceLROnPlateau 是 PyTorch 中的一种学习率调度器&#xff0c;主要用于在模型训练过程中根据某些指标&#xff08;如验证损失&#xff09;动态调整学习率。它是一种基于性能指标动态调整学习率的策略&#xff0c;而不是预定义的固定时间调整。 主要…...

Linux 搭建ftp服务

FTP是什么&#xff1f; FTP&#xff08;文件传输协议&#xff0c;File Transfer Protocol&#xff09;是一种用于在计算机之间传输文件的网络协议。它基于客户端-服务器模型&#xff0c;允许用户从远程服务器上传、下载和管理文件。 FTP的主要作用 文件传输&#xff1a;FTP最基…...

阳光电源嵌入式面试题及参考答案

讲一讲声明变量的时候应该注意哪些内容。 在声明变量时,首先要考虑变量的类型。不同的数据类型有不同的用途和占用的存储空间大小。例如,基本数据类型如整型(int)通常占用 4 个字节,用来存储整数;而浮点型(float)用于存储带有小数部分的数字,占用 4 个字节,双精度浮点…...

PS的功能学习(形状、文字、图层)

关于图层 如果是在一个已经有其他图层的文档界面下&#xff0c;拉一张新图进来&#xff0c;就会自动转换成智能对象 注意&#xff0c;放大之后再栅格化&#xff0c;是会根据原本的防矢量图规则放大之后&#xff0c;再变回像素图层&#xff0c;这个变回来的像素图层是“在原像素…...

项目实例_FashionMNIST_CNN

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…...

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的编解码,日志,比较器

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…...

2.1、模版语法

2.1.1、插值语法 1、代码示例 <body><!-- 准备容器 --><div id"app"><!-- 在data中声明的 --><!--1、 data中声明的变量 --><h1>{{msg}}</h1><h1>{{sayHello()}}</h1><!-- 不在data中的变量不可以 -->…...

最小二乘法拟合出二阶响应面近似模型

背景&#xff1a;根据样本试验数据拟合出二阶响应面近似模型&#xff08;正交二次型&#xff09;&#xff0c;并使用决定系数R和调整的决定系数R_adj来判断二阶响应面模型的拟合精度。 1、样本数据&#xff08;来源&#xff1a;硕士论文《航空发动机用W形金属密封环密封性能分析…...

【汽车】-- 常见的汽车悬挂系统

汽车悬挂系统是车辆的重要组成部分&#xff0c;其主要功能是连接车轮和车身&#xff0c;减缓路面颠簸对车身的影响&#xff0c;提高行驶的平顺性、舒适性和操控性。以下是常见的汽车悬挂系统类型及其特点&#xff1a; 1. 独立悬挂系统 每个车轮可以独立上下运动&#xff0c;不…...

VMware Workstation Pro 17 下载 以及 安装 Ubuntu 20.04.6 Ubuntu 启用 root 登录

1、个人免费版本 VMware Workstation Pro 17 下载链接怎么找&#xff1f;直接咕咕 VMware 找到如下链接。链接如下&#xff1a;Workstation 和 Fusion 对个人使用完全免费&#xff0c;企业许可转向订阅 - VMware 中文博客 点进去链接之后你会看到如下&#xff0c;注意安装之后仍…...

记录ubuntu22.04重启以后无法获取IP地址的问题处理方案

现象描述&#xff1a;我的虚拟机网络设置为桥接模式&#xff0c;输入ifconfig只显示127.0.0.1&#xff0c;不能连上外网。&#xff0c;且无法上网&#xff0c;用ifconfig只有如下显示&#xff1a; 1、sudo -i切换为root用户 2、输入dhclient -v 再输入ifconfig就可以看到多了…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...