javaEE-多线程编程-3

目录

java 常见的包 :

回调函数:

什么是线程:

第一个线程:

验证多线程执行:

内核:

调用sleep()方法:

执行结果分析:

线程创建的几种方式:

1.继承Thread类,重写run()方法.

2.实现Runnable接口,重写run()方法.

3.继承Thread类,重写run()方法.但使用匿名内部类

4.实现Runnable接口,重写run()方法,但使用匿名内部类:

5.使用lambda表达式(推荐)

Thread的构造方法

Thread的常用的属性:

1.ID:jvm自动分配的身份标识,不同线程不会重复

2.名称是调试的时候用到的

3.状态:

4.优先级:

5.是否后台线程:

6.是否存活:


在写代码的时候,可以用多进程编程,也可以用多线程编程.

多进程编在java中不太推荐,因为与多进程编程相关的api,在java标准库中都没有提供.

系统提供了多线程编程的api,在java标准库中,把这些api都封装了,在代码中可以直接使用.

并且在面对频繁创建和销毁进程的时候,多线程编程具有非常大的优势.效率非常高.

java 常见的包 :

1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。

2. java.lang.reflect:java 反射编程包;

3. java.net:进行网络编程开发包。

4. java.sql:进行数据库开发的支持包。

5. java.util:是java提供的工具程序包。(集合类等) 非常重要

6. java.io:I/O编程开发包

Thread类就是java.long包下的类,不需要引入包就能直接使用.

一个.java文件中,只能有一个类被public修饰,若该类没有被public修饰,就只能在该包中,被别的类引用.

一个进程至少会有一个线程,该进程的第一个线程就是main线程,也就是主线程的入口方法.

回调函数:

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

简单来说:回调函数就是把一段代码,向传参一样,传递给其它代码,这段代码会在某个时刻被调用执行.这就叫做回调.

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。

回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。如果代码立即被执行就称为 同步回调,如果过后再执行,则称之为 异步回调。

什么是线程:

⼀个线程就是⼀个"执⾏流".每个线程之间都可以按照顺序执⾏⾃⼰的代码.多个线程之间"同时"执⾏ 着多份代码

第一个线程:

创建一个Thread01类,让该类继承Thread类,重写Thread类的run()方法,

在主函数中实例化该类,调用该类的start()方法,这样,不需要我们手动调用run()方法,待线程创建好后,会在合适的时机被jvm自动调用.(这种风格的函数,就被称为"回调函数"callback)

调⽤start()⽅法,才真的在操作系统的底层创建出⼀个线程.

package Thread_;class MyThread01 extends Thread{@Overridepublic void run() {//重写run()方法//run()方法就是该线程的入口while (true){System.out.println("Thread run");}}
}
public class Thread01 {public static void main(String[] args) {Thread thread01 = new MyThread01();thread01.start();//必须要调用start()方法,才能开启线程while(true){System.out.println("main ");}}
}

当引入多线程之后,代码中就可以同时具备多个执行流了.

验证多线程执行:

可以通过jdk/bin/jconsloe.exe文件看进程状态.

先运行自己写的代码,让后进行下面的操作

内核:

操作系统的内核是操作系统最核心的功能模块.(管理硬件,给软件提供稳定的运行环境)

简单来说:内核态是非常重要的,不允许用户修改的,划分出用户态和内核态也是目的是为了稳定,以防自己的应用程序把硬件设备或软件资源给搞坏了.

操作系统=内核+应用程序.

一旦开始执行,线程就会飞快的循环起来,使cpu占用率较高,进一步提高电脑的功耗,为了不让循环跑的那么快,可以在循环体中设置Thread类的sleep()方法,让每隔一定时间运行一次,这样就能降低电脑的功耗.

调用sleep()方法:

sleep()方法调用时,会有受查异常,需要手动抛出.

Mythread类中的run()方法内的异常抛出只能以try-catch的形式,不能以throws的形式,因为run()方法是重写父类的方法,父类没有throws这个异常,若加上throws,就修改了方法签名,因此,子类重写run()方法的时候,也就只能以try-catch的形式抛出异常了.

以try-catch的形式抛出异常:

以throws的形式抛出异常:

时间转换单位:

1s=1000ms(毫秒)

1ms=1000(微妙)

1um=1000nm(纳秒)

上面的第一个线程代码,可以看出,main()方法中有一个死循环,在Thread01类的run()方法中也有一个死循环,一般来说,一个代码中出现两个死循环,只会运行一个,但实际上这两个死循环中的代码都被运行了,这就说明是两个线程在同时执行.

执行结果分析:

从执行的结果上可以看出,thread和main是随机交替出现的,也就是说,每隔一秒钟,thread和main被执行一次,但是谁先被执行,是无法确定的.

每次最开始打印的结果,可以看到:都是main第一次被打印,这是因为在创建MyThrow01线程的时候,虽然该线程不是第一个线程,还是会有一定开销的,这个开销比创建进程要低很多(但也不是没有),就是这一点点的开销,使得main线程每次在最开始执行的时候强到了先机.

(注意:main线程是第一线程)

线程创建的几种方式:

1.继承Thread类,重写run()方法.

也就是上面的这种方式.

package Thread_;class MyThread01 extends Thread{@Overridepublic void run() {//run()方法就是该线程的入口while (true){System.out.println("Thread run");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
public class Thread01 {public static void main(String[] args) {Thread thread01 = new MyThread01();thread01.start();//必须要调用start()方法,才能开启线程while(true){System.out.println("main ");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}

2.实现Runnable接口,重写run()方法.

Runnable接口需要搭配Thread类使用,才能真正在系统中创建出线程来
package Thread_;class MyThread02 implements Runnable{@Overridepublic void run() {while(true){System.out.println("Thread01 run()");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
public class Thread02 {public static void main(String[] args) {MyThread02 runnable = new MyThread02();Thread thread1 = new Thread(runnable);//Runnable接口需要搭配Thread类使用,才能真正在系统中创建出线程来thread1.start();while(true){System.out.println("main()");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}

3.继承Thread类,重写run()方法.但使用匿名内部类

Thread t=new Thread(){//这里写的{}表示要定义一个类,并且这个新类继承Thread,//且没有名字,用一次就不能再用了//{}中可以定义新类的属性和方法//此处的目的就是重写父类Thread的run()方法.@Overridepublic void run() {while(true){System.out.println("Thread run03");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
};

这里的thread变量名指向的是新创建的Thread的匿名内部类(子类),而不是Thread类.

4.实现Runnable接口,重写run()方法,但使用匿名内部类:

Thread构造方法的参数,传了Runnable的匿名内部类的实例.

5.使用lambda表达式(推荐)

lambda表达式原理:

Thread thread=new Thread(()->{    //这里的()是形参列表,在这里,不需要传参数//()的前面应该有个函数名,这里是匿名的,所以没有名字//->后面的{}是方法体,while(true){System.out.println("Thread run5");try{Thread.sleep(1000);}catch(InterruptedException o){throw new RuntimeException(e);}}
});

这里的规则是方法不能脱离类单独存在.

这几种方法都是等价的,作用都相同.

Thread的构造方法

1.构造方法:

前两个在前面创建线程的时候都提到了,

第三,四个:给线程起个名字:

在jcolsole.exe中就能看到线程名字被修改

自己创建的线程默认是按照Thread-0 1 2 ...创建的,线程之间的名字可以重复,起名字是为了方便调试.

Thread的常用的属性:

1.ID:jvm自动分配的身份标识,不同线程不会重复

2.名称是调试的时候用到的

3.状态:

线程有不同的状态:就绪状态,阻塞状态

4.优先级:

优先级⾼的线程理论上来说更容易被调度到,线程的优先级在java中,效果不是很明显

5.是否后台线程:

和后台线程相对应的是前台线程,当一个进程开始运行的时候,只有前台线程都运行结束,后台线程才会结束.

JVM会在⼀个进程的所有⾮后台线程结束后,才会结束运⾏。

目前代码创建的线程都是前台线程,都会阻止线程的结束,当全部都执行完了,才会结束整个进程.

设置线程为后台线程:在start之前setDaemon(true);此时,该线程就为后台线程

在start之前,给thread线程设置成了后台线程,在main函数之后,休眠2秒,thread线程就执行了2秒,打印了两遍,main线程结束了,thread线程为后台线程,也就结束了.

6.是否存活:

表示内核中的线程是否还存活,在start之前,还没有开始线程,isAlive为false,

只有调用了start,线程才开始执行,isAive才为true.

2s之后,run()已经结束,isAlive为false.

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

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

相关文章

怎么在idea中创建springboot项目

最近想系统学习下springboot,尝试一下全栈路线 从零开始,下面将叙述下如何创建项目 环境 首先确保自己环境没问题 jdkMavenidea 创建springboot项目 1.打开idea,选择file->New->Project 2.选择Spring Initializr->设置JDK->…

设计模式期末复习

一、设计模式的概念以及分类 是一套被反复使用,多数人知晓,经过分类编目,代码设计经验的总结,描述了在软件设计的过程中不断重复发生的问题,以及该问题的解决方案,他是解决特定问题的一系列套路&#xff0c…

Github——网页版上传文件夹

第一步:创建一个新的仓库或进入已存在的仓库页面 第二步:点进对应的文件夹下,然后 点击 “Upload files” 第三步:将文件夹拖拽到上传区域 打开资源管理器,将要上传的文件夹从计算机中拖拽到上传区域。 注意&#xf…

高级的SQL查询技巧有哪些?

成长路上不孤单😊😊😊😊😊😊 【14后😊///C爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于高级SQL查询技巧方面的相关内容&#xf…

FastStone 10.x 注册码

简介 FastStone Capture是一款经典好用的屏幕截图软件,在屏幕截图领域具有广泛的应用和众多优势。 软件基本信息 FastStone Capture体积小巧,占用内存少,这使得它在运行时不会给计算机系统带来过多的负担,即使在配置较低的电脑…

K8S详解(5万字详细教程)

目录 ​编辑 一、集群管理命令 二、命名空间 1. 获取命名空间列表 2. 创建命名空间 3. 删除命名空间 4. 查看命名空间详情 三、Pod 1. Pod概述 2. Pod相位状态 3. 管理命令 3.1 获取命名空间下容器(pod)列表 3.2 查看pod的详细信息 3.3 创建 && 运行 3.4 …

费舍尔信息矩阵全面讲述

费舍尔信息矩阵(Fisher Information Matrix) 费舍尔信息矩阵是统计学中一个非常重要的概念,尤其在参数估计、最大似然估计(MLE)和贝叶斯推断中具有广泛的应用。它反映了参数估计的不确定性程度,也可以用来…

Zookeeper的监听机制

Zookeeper的监听机制是其实现分布式协调服务的一个核心功能。 它允许客户端注册Watcher(观察者)来监听特定的Znode(节点)上的事件,当Znode的状态发生变化时,Zookeeper会向注册了Watcher的客户端发送通知。…

[原创](Modern C++)现代C++的第三方库的导入方式: 例如Visual Studio 2022导入GSL 4.1.0

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共23年] 职业生涯: 21年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delphi、XCode、Eclipse…

2002 - Can‘t connect to server on ‘192.168.1.XX‘ (36)

参考:2002 - Can‘t connect to server on ‘192.168.1.XX‘ (36) ubantu20.04,mysql5.7.13 navicat 远程连接数据库报错 2002 - Can’t connect to server on ‘192.168.1.61’ (36) 一、查看数据库服务是否有启动,发现有启动 systemctl status mysql…

漏洞检测工具:允许TRACE方法漏洞

允许TRACE方法漏洞 漏洞定义 TRACE方法是HTTP协议中定义的一种调试方法,主要用于测试或诊断Web服务器连接。Web服务器在配置时未正确禁用HTTP TRACE方法,从而允许客户端向服务器发送TRACE请求,并导致服务器返回可能包含敏感信息的响应。 漏…

linux socket编程之udp_dict_serve服务端--引入配置文件

注意:本篇博客只是对上一篇博客功能的增加 1.创建配置文件(翻译) Dict.txt apple: 苹果 banana: 香蕉 cat: 猫 dog: 狗 book: 书 pen: 笔 happy: 快乐的 sad: 悲伤的 run: 跑 jump: 跳 teacher: 老师 student: 学生 car: 汽车 bus: 公交车 love: 爱 hate: 恨 hell…

ESP32S3 使用LVGL驱动LCD屏(ST7789主控)

ESP32S3 使用LVGL驱动LCD屏(ST7789主控) 目录 1 分析原理图 2 驱动、点亮LCD(ST7789) 2.1 在工程中添加目录、文件 2.2 添加esp_lvgl_port组件 2.3 对工程进行必要的配置 2.4 编写必要代码 3 烧录、验证 1 分析原理图 要使用SOC驱动LCD屏&#…

Sigrity Optimize PI CapGen仿真教程文件路径

为了方便读者能够快速上手和学会Sigrity Optimize PI和 Deacap Generate 的功能,将Sigrity Optimize PI CapGen仿真教程专栏所有文章对应的实例文件上传至以下路径 https://download.csdn.net/download/weixin_54787054/90171471?spm1001.2014.3001.5503

2024年“羊城杯”粤港澳大湾区网络安全大赛 初赛 Web数据安全AI 题解WriteUp

文章首发于【先知社区】:https://xz.aliyun.com/t/15442 Lyrics For You 题目描述:I have wrote some lyrics for you… 开题。 看一下前端源码,猜测有路径穿越漏洞 http://139.155.126.78:35502/lyrics?lyrics../../../../../etc/passw…

NLP 中文拼写检测开源-03-hunspell 拼写纠正算法入门介绍 CSC

拼写纠正系列 NLP 中文拼写检测实现思路 NLP 中文拼写检测纠正算法整理 NLP 英文拼写算法,如果提升 100W 倍的性能? NLP 中文拼写检测纠正 Paper java 实现中英文拼写检查和错误纠正?可我只会写 CRUD 啊! 一个提升英文单词拼…

SpringCloud 运用(3)—— Nacos配置中心

上一篇:SpringCloud 入门(2)—— 跨服务调度-CSDN博客 Nacos是阿里巴巴开源的服务发现与配置管理基础设施,旨在帮助开发者更轻松地构建云原生应用。它提供了一组简单易用的特性集,支持动态服务发现、配置管理和服务管理…

门户系统需要压测吗?以及门户系统如何压力测试?

一、门户系统为什么要进行压力测试? 首先一点要明确一下,统一门户上线以后,将是所有应用系统的入口,对应门户稳定性要求较高,门户实现了统一入口和统一认证,系统宕机将影响其他系统使用。一般部署架构要求…

专题八:背包问题

> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:了解什么是记忆化搜索,并且掌握记忆化搜索算法。 > 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早…

SpringBoot核心:自动配置

有使用过SSM框架的,还记得曾经在spring-mybatis.xml配置了多少内容吗?数据源、连接池、会话工厂、事务管理,而现在Spring Boot告诉你这些都不需要了,简单的几个注解统统搞定,是不是很方便! 前言 SpringBoo…