多线程基础

news/2024/4/24 10:45:30/

1.多线程基础概念

多线程:让程序同时做多件事情

多线程作用:提高效率

并发:在同一时间,有多个指令在单个cpu上交替执行

并行:在同一时刻,有多个指令在多个cpu上同时执行

2.多线程的实现

(1)继承Thread类来实现多线程

//第一步:写一个类mythread继承Thread类
//第二步:重写run方法,run方法里面就是线程要执行的代码
//第三步:在测试类中创建mythread类的对象th,并用th.start();来启动线程

注意是调用start方法而不是run方法

Thread中的方法:

setName方法是设置线程名字

getName方法是获取线程名字

注意看

System.out.println(getName()+"helloworld");

这个语句直接使用了getName,是因为mythread1类是Thread的子类,子类可以直接调用父类的方法

package multithreading;
//第一步:写一个类mythread继承Thread类
//第二步:重写run方法,run方法里面就是线程要执行的代码
//第三步:在测试类中创建mythread类的对象th,并用th.start();来启动线程
public class mythread1 extends Thread{@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(getName()+"helloworld");}}
}

package multithreading;public class threaddemo {public static void main(String[] args) {var a = new mythread1();//为该线程起名a.setName("线程1");var b = new mythread1();b.setName("线程2");a.start();b.start();}
}

 运行结果可以看到线程1和线程2交替执行


(2)定义一个类去实现Runnable接口来实现多线程

//第一步:定义一个类去实现Runnable接口
//第二步:重写里面的Run方法
//第三步:在测试类里创建实现类的对象(也被称作任务对象)
//第四步:创建thread类的对象,形参就是你希望执行的线程的对象,即任务对象,再调用start()方法
package multithreading;
//第一步:定义一个类去实现Runnable接口
//第二步:重写里面的Run方法
//第三步:创建实现类的对象(也被称作任务对象)
//第四步:创建thread类的对象,形参就是你希望执行的线程的对象,即任务对象,再调用start()方法
public class MyRun implements Runnable{@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+"HelloWorld");}}
}
package multithreading;public class threaddemo1 {public static void main(String[] args) {MyRun m = new MyRun();Thread t1 = new Thread(m);t1.setName("线程1");Thread t2 = new Thread(m);t2.setName("线程2");t1.start();t2.start();}
}

 System.out.println(Thread.currentThread().getName()+"HelloWorld");

这个语句中的Thread.currentThread()是获取当前线程的对象


(3)利用Callable接口和FutureTask接口来实现多线程

//第三种方式可以获取多线程运行的结果//第一步:创建一个类MyCallable去实现Callable接口
//第二步:重写call(这个方法是有返回值的,返回多线程运行得到的结果)
//第三步:在测试类中,创建MyCallable类的对象(任务对象,表示多线程要执行的任务)
//第四步:创建FutureTask的对象(用来管理多线程运行的结果)
//第五步:创建Thread类的对象,并启动(表示线程)
package multithreading;
//第三种方式可以获取多线程运行的结果//第一步:创建一个类MyCallable去实现Callable接口
//第二步:重写call(这个方法是有返回值的,返回多线程运行得到的结果)
//第三步:在测试类中,创建MyCallable类的对象(任务对象,表示多线程要执行的任务)
//第四步:创建FutureTask的对象(用来管理多线程运行的结果)
//第五步:创建Thread类的对象,并启动(表示线程)import java.util.concurrent.Callable;public class MyCallable implements Callable<Integer> {//泛型和线程运行结果要一致@Overridepublic Integer call() throws Exception {int sum=0;for (int i = 1; i <= 100; i++) {sum+=i;}return sum;}
}
package multithreading;import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class threaddemo2 {public static void main(String[] args) throws ExecutionException, InterruptedException {//mc是线程对象,ft是用来管理传入的线程的结果的,t是用来启动线程的var mc  = new MyCallable();var ft = new FutureTask<Integer>(mc);var t =new  Thread(ft);t.start();System.out.println(ft.get());}
}

 三种实现方式的优缺点

多线程中常用成员方法

 

 设置优先级和获取优先级

优先级1~10,不设置就是默认的5,优先级越高,该线程抢占成功的概率就越大

守护线程:当非守护线程运行结束时,守护线程也就没有执行的必要了,会慢慢结束

礼让线程:让线程尽可能抢占均匀

插入线程:t.join();    把t线程插入到当前线程之前,当插入的线程结束后再执行之前那个线程

线程的生命周期



线程安全问题--同步代码块

当多个线程同时运行时,出现的不合理情况

if (ticket <= 0) {// 卖完了break;
} else {ticket--;System.out.println(Thread.currentThread().getName() + "在卖票,还剩下" + ticket + "张");
}

窗口三在卖票,还剩下98张
窗口一在卖票,还剩下98张
窗口一在卖票,还剩下96张
窗口三在卖票,还剩下95张
窗口二在卖票,还剩下95张
 

 这是出现了多个窗口同时卖同一张票的情况,因为多个线程同时运行到了某条语句

窗口一在卖票,还剩下0张
窗口三在卖票,还剩下-1张
 

这是出现负数票,因为运行过程中出现了脏数据 ,线程三运行到 判断票数时,票数还大于0,可当运行到   ticket--;时,其他线程在这之前已经   ticket--了,导致了出现负数

同步代码块

语法:

synchronized(任意对象) {
    多条语句操作共享数据的代码
}
 

当有多个线程时,这个(任意对象)必须是静态唯一的,就是说是唯一的锁,不然每个线程用各自的锁不就相当于没锁了吗

只要有一个线程进入该代码块,该块就被锁住,其他线程无法进入,当线程执行完毕出来,就自动解锁,

同步方法

同步方法不需要指定锁对象,而且同步方法可以锁住方法中所有代码,故同时只能有一个线程运行同步方法中的代码。

修饰符 synchronized 返回值类型 方法名(方法参数) {}

Lock锁

唤醒机制,生产者和消费者

Cook类

package lock;public class Cook extends   Thread{//表示Cook能创建线程对象@Overridepublic void run() {//1.写循环//2.写同步代码块//3.判断共享数据是否到达末尾(到达末尾)//4.判断共享数据是否到达末尾(没有到达末尾,就执行while(true)synchronized (Desk.lock){if(Desk.count==0){//总次数为0表示吃货已经吃饱break;}else{//还有次数if(Desk.foodFlag==1) {//如果桌子上有面条,厨师等吃货吃完这碗就好了try {Desk.lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}else{//桌子上没有面条,厨师就做面条System.out.println("厨师开始做面条");//做完就要修改桌子数据,0改成1Desk.foodFlag =1;//唤醒吃货来吃Desk.lock.notifyAll();}}}}
}

Foodie类

package lock;public class Foodie extends Thread{@Overridepublic void run() {//1.写循环//2.写同步代码块//3.判断共享数据是否到达末尾(到达末尾)//4.判断共享数据是否到达末尾(没有到达末尾,就执行核心逻辑)while(true)synchronized (Desk.lock){if(Desk.count==0)break;else{//先判断桌子上是否有面条//没有就等//有就吃//吃完之后唤醒厨师线程//总次数减1//修改桌子状态,就是本来桌子上有面条,是1,吃完就没了,就要修改桌子状态为0if(Desk.foodFlag==0){//桌子上没有面条//没有就等待try {Desk.lock.wait();//等待的方法要用锁对象去调用} catch (InterruptedException e) {throw new RuntimeException(e);}}else{//表示桌子上有面条//有就开吃//能吃的面条湾数减一Desk.count--;System.out.println("吃货在吃面条,还能再吃"+Desk.count +"碗");//吃完就唤醒厨师Desk.lock.notifyAll() ;//表示唤醒绑定该锁对象的所以线程//修改桌子状态Desk.foodFlag  =0;}}}}
}

Desk类

package lock;public class Desk {//该类控制生产者和消费者的执行//0:没食物,1:有食物public static  int  foodFlag =0;//总个数public  static  int count =10;//锁对象//只是名字是锁,用来做  synchronized ()的锁对象public  static Object lock = new Object();}

测试类

package lock;public class ThreadDemo {public static void main(String[] args) {//完成生产者和消费者的代码//实现线程轮流交替执行的效果//创建线程的对象Cook c = new Cook();Foodie f = new Foodie();//给线程设置名字c.setName("厨师");f.setName("吃货");//开启线程c.start();f.start();}}

运行结果

唤醒机制:阻塞队列

线程状态

线程池

 自定义线程池

 


http://www.ppmy.cn/news/48253.html

相关文章

电脑卡顿反应慢怎么处理?电脑提速,4个方法!

案例&#xff1a;电脑卡顿反应慢怎么处理&#xff1f; 【快帮帮我&#xff01;我的电脑现在越用越卡了&#xff0c;有时候光是打开一个文件都要卡好几分钟&#xff0c;我真的太难了&#xff0c;有什么可以加速电脑反应速度的好方法吗&#xff1f;万分感谢&#xff01;】 随着…

es7.x集群部署-多台物理机部署-docker环境部署-docker-compose管理

es集群部署文档 部署es服务的三台服务器的ip和host分分别是&#xff1a; iphost_name192.168.1.2web02192.168.1.3storage02192.168.1.4Storage03 这个配置需要在服务器上编写对应的hosts文件&#xff0c;然后才可以使用host进行配置。 本次部署没有外挂配置文件&#xff0…

手把手教你 DVOL

分享本文在朋友圈的读者可获得本文数据和 Python 代码。留个言说已分享&#xff08;不用截屏&#xff09;我相信你&#xff0c;我会发给你百度盘下载链接。 本文长度为 6393 字&#xff0c;建议阅读 32 分钟 题图&#xff1a;SignalPlus Dashboard 0 引言 Deribit volatility (…

Qt音视频开发37-识别鼠标按下像素坐标

一、前言 在和视频交互过程中,用户一般需要在显示视频的通道上点击对应的区域,弹出对应的操作按钮,将当前点击的区域或者绘制的多边形区域坐标或者坐标点集合,发送出去,通知其他设备进行处理。比如识别到很多人脸,用户单击某个人脸后指定对该人脸进行详细的信息查询等;…

记录webpack安装

在安装完 yarn以后&#xff0c;yarn安装_阿巴资源站的博客-CSDN博客 然后开始安装webpack 看网上有人说npm install webpack-cli -g没成功&#xff0c;于是没试直接跳过坑 sudo npm install webpack -g --unsafe-permtrue --allow-root 然后提示&#xff1a; webpack -v On…

RabbitMQ:消息中间件

文章目录 概念管理界面简介4中常见交换器类型1.Direct交换器:2.Fanout交换器3.Topic交换器4.headers交换器 对象类型消息传递同步等待使用代码创建队列待续...... 概念 在微服务架构中项目之间项目A调用项目B 项目B调用项目C项目C调用项目D。。 用户必须等待项目之间内容依次的…

【闲聊杂谈】HTTPS原理详解

HTTPS和HTTP的区别 HTTP虽然使用极为广泛, 但是却存在不小的安全缺陷, 主要是其数据的明文传送和消息完整性检测的缺乏, 而这两点恰好是网络支付, 网络交易等新兴应用中安全方面最需要关注的。 关于 HTTP的明文数据传输, 攻击者最常用的攻击手法就是网络嗅探, 试图从传输过程…

亚马逊广告运营常见问答

同一个广告组中&#xff0c;建议投放多少个关键词呢&#xff1f; 同一广告组下我们建议投放的关键词至多不超过50个。 1.如关键词设置过少&#xff08;且前期无法用数据佐证其精准引流效果时&#xff09;&#xff0c;有可能导致广告曝光量较低&#xff1b; 2.如关键词设置过多…

SAS学习第9章:卡方检验之适合性检验与独立性检验

卡方检验就是统计样本的实际观测值与理论推断值之间的偏离程度&#xff0c;实际观测值与理论推断值之间的偏离程度就决定卡方值的大小&#xff0c;如果卡方值越大&#xff0c;二者偏差程度越大&#xff1b;反之&#xff0c;二者偏差越小&#xff1b;若两个值完全相等时&#xf…

查询练习:按等级查询

建立一个 grade 表代表学生的成绩等级&#xff0c;并插入数据&#xff1a; CREATE TABLE grade (low INT(3),upp INT(3),grade char(1) );INSERT INTO grade VALUES (90, 100, A); INSERT INTO grade VALUES (80, 89, B); INSERT INTO grade VALUES (70, 79, C); INSERT INTO …

U-Boot 命令使用

进入 uboot 的命令行模式以后输入“help”或者“&#xff1f;”&#xff0c;然后按下回车即可查看当前 uboot 所 支持的命令&#xff0c;如图 所示&#xff1a; 我们输入“help(或?) 命令名”既可以查看命令的详细用法&#xff0c;以“bootz”这 个命令为例&#xff0c;我们输…

使用FFMPEG库将YUV编码为H264

准备 ffmpeg 4.4 p准备一段yuv420p的格式的视频原始数据 这里我们使用命令直接提取 ffmpeg -i .\beautlWorld.mp4 -pixel_format yuv420p -s 1280x720 yuv420p_1280x720.yuv 编码流程 大致可以分为以下几步&#xff1a; 1.初始化编码器并设置参数 2.初始化AVPacket和AVFr…

适应大、中、小型医院的手术麻醉临床信息管理系统源码

手术麻醉管理系统是一款专门用于医院手术麻醉管理的软件系统&#xff0c;它可以帮助医院和医生更好地管理手术麻醉过程&#xff0c;提高手术麻醉的质量和安全性。本文将介绍手术麻醉管理系统的实现、功能概述、主要功能、系统设置、麻醉管理、术中记录、苏醒室记录、PCA实施及管…

gRPC(Java) keepAlive机制研究

文章目录 结论Client端KeepAlive使用入口简要时序列表 Server端KeepAlive使用入口简要时序列表KeepAliveEnforcer 基于java gRPC 1.24.2 分析 结论 gRPC keepAlive是grpc框架在应用层面连接保活的一种措施。即当grpc连接上没有业务数据时&#xff0c;是否发送pingpong,以保持连…

快手社招Java后端开发岗面试,被问麻了

社招面试是基于你的工作项目来展开问的&#xff0c;比如你项目用了 xxx 技术&#xff0c;那么面试就会追问你项目是怎么用 xxx 技术的&#xff0c;遇到什么难点和挑战&#xff0c;然后再考察一下这个 xxx 技术的原理。 今天就分享一位快手社招面经&#xff0c;岗位是后端开发&…

陪诊小程序开发|陪诊软件开发功能特色

为了提升就医的服务质量&#xff0c;人们对于医疗服务的需求也在不断提高。这几年随着生活水平和医疗水平的提升&#xff0c;陪诊服务越来越受到人们的重视和青睐&#xff0c;越来越多的人开始意识到&#xff0c;陪伴和关爱在疾病治疗过程中的重要性&#xff0c;为了更好的规划…

第四章 面向对象(OOP)

目录 一、编程思想 1.1. 面向对象 1.2. 面向过程 1.3.举例说明&#xff08;把大象装进冰箱&#xff09; 1.4.二者的联系与区别 1.5.面向对象的三个阶段 1.6.什么是类&#xff0c;什么是实例&#xff0c;二者的联系 二、面向对象三大特征 2.1 封装 2.2 继承 2.3 多态…

2023年全国最新二级建造师精选真题及答案56

百分百题库提供二级建造师考试试题、二建考试预测题、二级建造师考试真题、二建证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 11.关于施工企业项目经理部的说法&#xff0c;正确的是&#xff08;&#xff09;。 A.项目经…

学习风`宇博客用户权限菜单模块

文章目录 用户-角色-菜单-资源 各表关系图菜单 和 路由菜单表及分析分析 /api/admin/user/menus接口MenuServiceImpl#listUserMenus接口返回示例及分析 前端代码分析menu.jsSideBar.vue 接口权限控制资源表 及 分析分析 WebSecurityConfig权限控制整体流程先说登录UserDetailsS…

MATLAB应用笔记

其他 1、NaN值 MATLAB判断数据是否为NaN可以直接使用函数&#xff1a;isnan() 三、数据分析 1、相关性 均值、方差、协方差、标准差、相关系数 mean() %均值 nanmean()%去除NAN值求均值 var() %方差 cov() %协方差 std() %标准差 corrcoef(B,b) %R 相关系数plot()…