Java基础知识(12)

Java基础知识(12)

(包括:多线程)

目录

Java基础知识(12)

一.多线程

1. 多线程基础

2. 多线程的实现方式

【1】继承Thread类的方式进行实现

【2】实现Runnable接口的方式进行实现

【3】利用Callable接口和Future接口方式实现

3.多线程三种实现方式对比

4. 常见的成员方法

5.线程的生命周期

6. 同步代码块

7. 同步方法

8. Lock锁

9.死锁(这是一种错误)

10.生产者和消费者(等待唤醒机制)

11. 线程的状态

12. 线程池

[1]主要核心原理

[2] 线程池代码实现

【3】什么是最大并行数?

【4】线程池多大合适呢(了解)

13.多线程额外拓展(实际开发用的少,但面试的时候喜欢问)


一.多线程

1. 多线程基础

(1)什么是多线程

有了多线程,我们就可以让程序同时做多件事情

(2)多线程的作用:提高效率

(3)多线程的应用场景

只要你想让多个事情同时运行就需要用到多线程

比如:软件中的耗时操作、所有的聊天软件、所有的服务器

(2)并发和并行

1.并发:在同一时刻,有多个指令在单个CPU上交替执行

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

2. 多线程的实现方式

【1】继承Thread类的方式进行实现

(1)自己定义一个类继承Thread

(2)重写run方法

(3)创建子类的对象,并启动线程

(4)案例

public class MyThread extends Thread{

@override

public void run(){

//书写线程要执行代码

for(inti=0;i<100;i++){

System.out.println("Helloworld");

}}}

public static void main(string[]args){

MyThread t1 = new MyThread();

//开启线程I

t1.start();

}

【2】实现Runnable接口的方式进行实现

(1)自己定义一个类实现Runnable接口

(2)重写里面的run方法

(3)创建自己的类的对象

(4)创建一个Thread类的对象,并开启线程

(5)案例

public class MyRun implements Runnable{

@0verride

public void run(){

//书写线程要执行的代码

for(inti=0;i<100;i++){

System.out.printin("HelloWorld!");

}}}

public static void main(string!args){

//创建MyRun的对象

//表示多线程要执行的任务

MyRun mr= new MyRun();

//创建线程对象

Thread t1 = new Thread(mr);

//开启线程

t1.start();

}

【3】利用Callable接口和Future接口方式实现

特点:可以获取到多线程运行的结果(重要)

(1)创建一个类MyCa11able实现Ca1lable接口

(2)重写ca11 (是有返回值的,表示多线程运行的结果)

(3)创建MyCallable的对象(表示多线程要执行的任务)

(4)创建FutureTask的对象(作用管理多线程运行的结果)

(5)创建Thread类的对象,并启动(表示线程)

(6)案例

public class Mycallable implements Callable<Integer>(

@0verride

public Integer call()throws Exception{

//求1~188之间的和

int sum =0;

for(inti=1;i<=100;i++){

sum = sum +i;

}

return sum;

}}

public static void main(string[]args){

//创建MyCallable的对象(表示多线程要执行的任务)

MyCallable mc = new MyCallable();

//创建FutureTask的对象(作用管理多线程运行的结果)

FutureTask<Integer>ft=new FutureTask<>(mc);

//创建线程的对象

Thread t1 = new Thread(ft);

//启动线程

t1.start();

//获取多线程运行的结果

Integer result=ft.get();

System.out.println(result);

}}

3.多线程三种实现方式对比

优点

缺点

继承Thread类

编程比较简单,可以直接使用Thread类中的方法

可以扩展性较差,不能再继承其他的类

实现Runnable接口

扩展性强,实现该接口的同时还可以继承其他的类

编程相对复杂,不能直接使用Thread类中的方法

实现Ca1lable接口

只有实现Ca1lable接口这种方法可以获取多线程的结果

4. 常见的成员方法

(1)String getName() 返回此线程的名称

(2)void setName(String name) 设置线程的名字(构造方法也可以设置名字)

(3)static Thread currentThread() 获取当前线程的对象

(4)static void sleep(long time) 让线程休眠指定的时间,单位为毫秒

(5)setPriority(int newPriority) 设置线程的优先级

(最小1,最大10,默认5)

(优先级越高只是说明抢到线程的概率高,但并不绝对)

(6)final int getPriority() 获取线程的优先级

(7)final void setDaemon(boolean on) 设置为守护线程(true为设置)

(细节:当其他的非守护线程执行完毕之后,守护线程会陆续结束)

(8)public static void yield() 出让线程/礼让线程 

(当该线程执行后会出让CPU执行权,然后所有线程重新抢夺执行器,会让线程执行的更均匀一点。)

(9)public static void join() 插入线程/插队线程

5.线程的生命周期

sleep方法会让线程睡眠,睡眠时间到了之后,立马就会执行下面的代码吗?

不会,会进入就绪态等待获得执行权。

6. 同步代码块

(1)把操作共享数据的代码锁起来

(2)格式:

synchronized(锁){

操作共享数据的代码

}

//锁对象,一定要是唯一的:static object obj= new object();

特点1:锁默认打开,有一个线程进去了,锁自动关闭

特点2:里面的代码全部执行完毕,线程出来,锁自动打开

7. 同步方法

(1)就是把synchronized关键字加到方法上

(2)格式:

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

特点1:同步方法是锁住方法里面所有的代码

特点2:锁对象不能自己指定,由Java指定

非静态方法: this(锁对象)

静态方法:当前类的字节码文件对象(锁对象)(一般用这个!!!)

(3)StringBuilder和StringBuffer

两者的方法基本相同,但StringBuilder在多线程时不安全,此时应用StringBuffer

8. Lock锁

(1)产生原因

虽然我们可以理解同步代码块和同步方法的锁对象问题

但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁

为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock

Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作

(2)方法

Lock中提供了获得锁和释放锁的方法

void lock():获得锁 手动上锁

void unlock():释放锁 手动释放锁

(3)创建

Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来实例化

ReentrantLock的构造方法

ReentrantLock():创建一个ReentrantLock的实例

(4)案例

public void run(){

while(true){

//同步代码块

Lock.lock();//2 //3

try {

if(ticket == 100){

break;

}else{

Thread.sleep(10);

ticket++;

System.out.println(getName())

}

}catch(InterruptedException e){

e.printstackTrace();

} finally{

Lock.unlock();

}

Try-catch-finally可以确保一定会释放锁。

9.死锁(这是一种错误)

以后注意千万不要让两个锁嵌套起来

10.生产者和消费者(等待唤醒机制)

生产者消费者模式是一个十分经典的多线程协作的模式

[1]消费者执行过程

(1)判断東子上是否有食物

(2)如果没有就等待

(3)如果有就开吃

(4)吃完之后,唤醒厨师继续做

[2] 生产者执行过程

(1)判断桌子上是否有食物

(2)有:等待

(3)没有:制作食物

(4)把食物放在桌子上

(5)叫醒等待的消费者开吃

[3] 生产者和消费者(常见方法)

void wait() 当前线程等待,直到被其他线程唤醒

void notify() 随机唤醒单个线程

void notifyA11() 唤醒所有线程

synchronized(Desk.lock){

Desk.lock.wait();//让当前线程跟锁进行绑定,不然一会唤醒总不能把电脑所以进程都唤醒吧

Desk.lock.notifyA11();

}

[3] 等待唤醒机制(阻塞队列方式实现)

(1)put数据时:放不进去,会等着,也叫做阻塞。

(2)take数据时:取出第一个数据,取不到会等着,也叫做阻塞。

(3)阻塞队列内部有锁,再把它写在里面就会形成死锁

(4)ArrayBlockingQueue:底层是数组,有界

(5)LinkedBlockingQueue:底层是链表,无界,但不是真正的无界,最大为int的最大值。

(6)细节:生产者和消费者必须使用同一个阻塞队列(在main中创建)

11. 线程的状态

(1)新建状态(NEW)    --> 创建线程对象

(2)就绪状态(RUNNABLE)      à start方法

(3)阻塞状态(BLOCKED)       à无法获得锁对象

(4)等待状态(WAITING)        àwait方法

(5)计时等待(TIMED WAITING)       àsleep方法

(6)结束状态(TERMINATED)       à全部代码运行完毕

12. 线程池

[1]主要核心原理

① 创建一个池子,池子中是空的

② 提交任务时,池子会创建新的线程对象,任务执行完毕,线程归还给池子

下回再次提交任务时,不需要创建新的线程,直接复用已有的线程即可

③ 但是如果提交任务时,池子中没有空闲线程,也无法创建新的线程,任务就会排队等待

[2] 线程池代码实现

(1)步骤

①创建线程池

②提交任务

③所有的任务全部执行完毕,关闭线程池(一般不会关闭)

(2)方法

Executors:线程池的工具类通过调用方法返回不同类型的线程池对象。

public static ExecutorService newCachedThreadPool() 创建一个没有上限的线程池(最大为int的最大值。)

public static ExecutorService newFixedThreadPool(int nThreads) 创建有上限的线程池

(3)案例

//1.获取线程池对象

ExecutorService pool1 = Executors.newCachedThreadPool()

//2.提交任务

poo11.submit(new MyRunnable());

//3.销毁线程池

poo11.shutdown();

【3】什么是最大并行数?

如:电脑为4核8线程,则最大并行数为8

//向Java点拟机返回可用处理器的数目

int count =Runtime.getRuntime().availableProcessors();

System.out.println(count);

即可获取本电脑的最大并行数

【4】线程池多大合适呢(了解)

CPU 密集型运算 最大并行数 +1(计算多)

I/0 密集型运算 最大并行数*期望CPU 利用率*总时间(CPU计算时间+等待时间)/ CPU计算时间(读取数据多)

13.多线程额外拓展(实际开发用的少,但面试的时候喜欢问)

在仅我可见中

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

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

相关文章

一文搞懂什么是外贸企业邮箱?

一文搞懂什么是外贸企业邮箱&#xff1f;外贸企业邮箱&#xff0c;也就是外贸行业使用的企业邮箱系统&#xff0c;一般需要具备海外抵达率高、安全稳定等特点&#xff0c;通过外贸企业邮箱&#xff0c;企业可以和国内国外的客户或者同事进行业务的沟通交流。 一、什么是外贸企…

asp.net mvc使用IHttpModule拦截所有请求,包括资源文件

目录 HttpApplication 类 添加App_Code文件夹 MyHttpModel2 Web.config添加配置&#xff0c;在iis模块中生效 项目发布后&#xff0c;察看注册的自定义模块 框架集&#xff1a;.NET Framework 4.7web框架&#xff1a;asp.net mvc 5 HttpApplication 类 HttpApplication 类…

TensorFlow与PyTorch:哪个更适合深度学习项目?

TensorFlow和PyTorch都是当前深度学习领域中非常流行和强大的框架&#xff0c;它们各有优势和特点。选择哪一个框架往往取决于具体的项目需求、团队熟悉度以及社区支持等因素。下面是对两者的一些比较&#xff0c;帮助你根据不同的需求选择最合适的框架&#xff1a; ### 1. 易…

gtk_overviewGTK入门

GTK入门 Gtk概述 GUI GUI 含义&#xff1a; &#xff08;Graphics User Interface&#xff09; 图形用户界面&#xff0c; 是计算机与使用者之间的对话接口&#xff0c; 是计算机重要的组成部分&#xff0c; 比如说咱们使用电脑或手机看到的 Windows 的桌面或 wps 软件显示…

记录下搭高可用集群中Hadoop的几个配置

不断补充中... DataNode的配置&#xff1a; 假设我有5台服务器&#xff0c;分别是hadoop100-104&#xff0c;我现在需要在100和101上配置NameNode&#xff0c;在102-104上配DataNode&#xff0c;我需要在我的workers文件中增加如下内容 [atguiguhadoop102 hadoop]$ vim /opt…

YOLOV5加入Convnext模块,助力涨点!

我们找到models文件夹中的common.py文件,添加CNeB模块,如下 ########################convnext############################# class Block(nn.Module):r""" ConvNeXt Block. There are two equivalent implementations:(1) DwConv -> LayerNorm (channels…

gorm-sharding分表插件升级版

代码地址&#xff1a; GitHub - 137/gorm-sharding: Sharding 是一个高性能的 Gorm 分表中间件。它基于 Conn 层做 SQL 拦截、AST 解析、分表路由、自增主键填充&#xff0c;带来的额外开销极小。对开发者友好、透明&#xff0c;使用上与普通 SQL、Gorm 查询无差别.解决了原生s…

传统鞋业如何转型?3D数字化技术让鞋业品牌焕发新机!

数字经济时代&#xff0c;3D数字化技术在各行业都得到广泛应用&#xff0c;这其中&#xff0c;传统的鞋服行业的发展也受到了3D数字化技术的影响&#xff0c;产生了深刻的变化&#xff0c;越来越多的鞋企品牌开始尝试3D数字化营销。 比如&#xff0c;时尚运动品牌VANS就在官网上…

论文AIGC检测让毕业生头疼,如何有效降低AI查重率!

在准备毕业论文的过程中&#xff0c;不知道大家有没有跟我一样&#xff0c;遇到这样棘手的问题。我们都知道在撰写完论文后&#xff0c;进行论文查重是我们必不可少的一步。于是&#xff0c;我拿着论文进行了论文重复率的检测&#xff0c;发现重复率只有2.8%&#xff0c;看到这…

探案录 | KingbaseES+SqlSugar为医疗用户排忧解难

在2024年的初春&#xff0c;某大型三甲医院的CT预约系统上线测试&#xff0c;如同新芽破土&#xff0c;充满了希望与活力。然而&#xff0c;仅仅两天后&#xff0c;一个技术难题如同迷雾中的幽灵&#xff0c;悄然出现&#xff1a;The connection pool has been exhausted…… 福…

Python 继承顺序

继承顺序的逻辑是非常重要的,它决定了在使用子类的属性和方法时,Python 解释器的搜索顺序。 在 Python 中,当一个类继承自多个父类时,解释器会按照一定的顺序搜索属性和方法。这个搜索顺序被称为方法解析顺序(Method Resolution Order, MRO)。 假设我们有以下三个类: class …

三相两电平逆变器的Simulink仿真建模及SPWM

三相两电平逆变器的介绍 三相两电平逆变器的电路结构如下图所示&#xff0c;作为非常基本的电力电子电路&#xff0c;众多教科书中均有对该电路的原理介绍&#xff0c;本文不再对原理进行赘述&#xff0c;主要目的在于提供simulink仿真电路。下图即为三相两电平逆变器电路结构…

图文并茂:解析Spring Boot Controller返回图片的三种方式

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 图文并茂&#xff1a;解析Spring Boot Controller返回图片的三种方式 前言使用Base64编码返回图片使用byte数组返回图片使用Resource对象返回图片图片格式转换与性能对比 前言 在互联网的世界里&…

AI雷达智能销售名片小程序源码系统+企业商城+公司动态 带完整的安装代码包以及安装搭建教程

在数字化时代&#xff0c;企业的销售模式正在经历一场深刻的变革。为了更好地满足市场需求&#xff0c;提升销售效率&#xff0c;罗峰给大家分享一款集AI雷达智能销售名片、企业商城、公司动态于一体的源码系统。该系统不仅配备了完整的安装代码包&#xff0c;还附有详细的安装…

批量自定义重命名,一键添加顺序编号,文件夹管理更高效!

我们经常需要对文件夹进行管理和整理。然而&#xff0c;当面对大量需要改名的文件夹时&#xff0c;手动逐个修改不仅效率低下&#xff0c;还容易出错。那么&#xff0c;有没有一种方法能够批量自定义重命名文件夹&#xff0c;并在名称后自动添加顺序编号呢&#xff1f;答案是肯…

Makefile解析(ARM LINLON V5/V7 VPU firmware tools例)

根目录Makefile 初始化一些变量 TARGETS : model executiontb cpu ROOT_DIR?$(abspath $(CURDIR)) OUT_DIR?$(abspath $(CURDIR)) ADDR_FILE:$(ROOT_DIR)/build/mmu_addr.txtmake all 执行 make help all: help.PHONY后面跟的目标都被称为伪目标&#xff0c;也就是说我们 mak…

ABC352编程笔记

ABC352 编程笔记 题意&#xff1a;输入&#xff0c;四个数 a , b , c , d a,b,c,d a,b,c,d&#xff0c;若 d d d 在 c , d c,d c,d 之间&#xff0c;则输出 Yes&#xff0c;否则输出 No。 正解&#xff1a;直接判断。 #include <bits/stdc.h> //#define int long lo…

【学习笔记】软件工程概述

简介 程序是人们为了完成特定的功能编制的一组指令集&#xff0c;它由计算机的语言描述&#xff0c;并且能在计算机系统上执行。而软件不仅包括程序&#xff0c;还包括程序的处理对象——数据&#xff0c;以及与程序开发、维护和使用相关的图文资料。 软件有以下几个特点&…

vscode正则匹配技巧

写正则表达式 下面是匹配加粗的单词或空格 \*\*[a-zA-Z\s]*\*\*vscode提取加粗的内容 altenter&#xff0c;再ctrlC复制选中的内容出来

DDD面试题:DDD聚合和表的对应关系是什么 ?(来自蚂蚁面试)

尼恩说在前面&#xff1a; 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如字节、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; DDD 的外部接口调用&#xff0c;应该放在…