多线程01(二)

简介: 多线程01

3.3变形写法.

  • 说明:在有时候我们只是临时使用一次线程,此时就没必要专门定义线程类,浪费资源。那么我们就可以通过以下两种写法实现多线程。

3.3.1在同一个文件里面创建Thread子类.


3.3.2匿名内部类.

补充lambda表达式写法。


3.4注意事项.

  1. 子线程之间的运行时随机的,到底运行谁,由CPU分配时间片决定。
  2. 不是main线程执行结束后才执行子线程。程序是先从main方法开始执行的(即从main线程开始执行),如果main方法里执行了其他线程的start方法,其它线程就会进入就绪状态,这时就看CPU分配时间片给谁,谁就执行。
  3. 如果自己手动通过线程对象调用run()方法,那么就只是调用一个普通方法,没有启动多线程模式。  
  4. run()方法由JVM调用,什么时候调用,执行的过程控制都有操作系统的CPU调度决定。  
  5. 想要启动多线程,必须调用start方法。  
  6. 一个线程对象只能调用一次start()方法启动,如果重复调用了,则将抛出异常“IllegalThreadStateException”

4.实现Runable接口方式.

  • Java有单继承的限制,当我们无法继承Thread类时,那么该如何做呢?在核心类库中提供了Runnable接口,我们可以实现Runnable接口,重写run()方法,然后再通过Thread类的对象代理启动和执行我们的线程体run()方法。

4.1使用步骤.

  1. 定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
  2. 创建Runnable实现类的实例,并以此实例作为Thread的target参数(线程要执行的内容)来创建Thread对象,该Thread对象才是真正的线程对象。
  3. 调用线程对象的start()方法,启动线程。调用Runnable接口实现类的run方法。

4.2代码演示.

  • 定义Runnable接口实现类.

  • 测试:


4.3变形写法.

4.3.1在同一个文件里面创建Runnable接口实现类.


4.3.2匿名内部类方式.

  • 写法一:未使用Lambda表达式。

  • 写法二:使用Lambda表达式。


4.4注意事项.

  1. 通过实现Runnable接口,使得该类有了多线程类的特征。所有的分线程要执行的代码都在run方法里面。
  2. 在启动的多线程的时候,需要先通过Thread类的构造方法Thread(Runnable target) 构造出对象,然后调用Thread对象的start()方法来运行多线程代码。
  3. 实际上,所有的多线程代码都是通过运行Thread的start()方法来运行的。因此,不管是继承Thread类还是实现Runnable接口来实现多线程,最终还是通过Thread的对象的API来控制线程的,熟悉Thread类的API是进行多线程编程的基础。
  4. 说明:Runnable对象仅仅作为Thread对象的target,Runnable实现类里包含的run()方法仅作为线程执行体。可以理解为 Runnable对象就是一个数据体,里面包含了线程要执行的内容。而实际的线程对象依然是Thread实例,只是该Thread线程负责执行其target的run()方法。

5.继承Thread类和实现Runnable接口两种方式对比.

  1. Thread类实际上也是实现了Runnable接口的类。
  2. 继承Thread方式适合线程之间处理各自任务(不共享资源)情况。
  3. 实现Runnable接口比继承Thread类所具有的优势:
  1. 避免了单继承的局限性;
  2. 多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源;
  3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。

6.相关方法.

6.1设置线程名.

  • 不设置线程名,默认是:Thread-0、Thread-1、Thread-2....这样命名。可以在线程的 run方法里面获取当前线程名测试 :Thread.currentThread().getName()
  • 手动设置线程名:
  • 继承Thread类方式:
  • 通过创建的线程对象调用:setName("线程名");方法进行设置;
  • 在线程类里面定义带参构造函数,然后调用父类构造函数。如:

  • 实现Runnable接口方式:


6.2设置线程休眠- .

  1. Thread.sleep():是Thread类的一个静态方法。作用:使当前线程休眠,进入阻塞状态(暂停执行),简单理解就是“线程暂停方法”。该方法可接收长整型毫秒和整型纳秒,可读性差(因为需要根据毫秒数或者纳秒数换算成其它时间单位)。
  2. TimeUnit.SECONDS.sleep():是 concurrent 包下的一个类,提供了可读性更好的线程暂停操作。里面提供了很多枚举类,如:

枚举

单位

DAYS

HOURS

小时

MINUTES

分钟

SECONDS

MILLISECONDS

毫秒(千分之一秒)

MICROSECONDS

微秒(一百万分之一秒(就是毫秒/1000))

NANOSECONDS

毫微秒(十亿分之一秒(就是微秒/1000))

  • 使用方式如下:

  • 除了枚举之外可以进行时间转换:


6.3设置&获取线程优先级.

  • getPriority() :返回线程优先级;
  • setPriority(int newPriority) :改变线程的优先级,范围在[1,10]之间。

6.4join方法.

  • join方法的作用是:在当前 线程执行的某个阶段,加入并执行其它线程。

  • 案例:


6.5yield方法.

  • yield方法的作用是当前正在运行的线程放弃CPU资源,重新回到就绪状态.
  • 案例:


6.6stop方法.

  • stop():已过时,不建议使用。强行杀死执行,直接进入死亡状态。run()即刻停止,可能会导致一些清理性的工作得不到完成,如文件,数据库等的关闭。同时,会立即释放该线程所持有的所有的锁,导致数据得不到同步的处理,出现数据不一致的问题。比如转账转了一半,突然停止。
  • 案例演示:

  • 运行结果:

  • 当线程2运行到第10次的时候就会暴力停止线程1的运行。但是从结果上发现,当线程2运行完第10次后,线程1又运行了一次,然后才被停止的,这是因为当线程2执行完第10次的输出语句后,还没来得及执行暴力停止线程1的代码,CPU马上给线程1分配时间片,线程1运行,然后CPU再给线程2分配时间片,线程2运行,马上暴力停止线程1.
  • 这样会导致线程1在停止的时候没有来得及处理后事,不安全。就好比,你在工厂里面生成产品,别人突然叫你停止生产,连给你关闭设备的时间都没有留。正确的应该是先提前通知你要停止生产了,给你时间关闭设备。

相关文章
|
监控 JavaScript 前端开发
使用Vue.js开发员工上网行为监控的实时数据展示页面
使用Vue.js开发的实时员工上网行为监控页面,展示员工访问的网站、应用和时间等数据。页面响应式设计,适应不同设备。通过Vue组件显示实时数据,如`<li v-for="activity in activities">`循环渲染。数据定时更新,利用Vue的生命周期钩子和axios从服务器获取并自动刷新,确保数据的时效性。该页面有助于管理者即时了解员工网络活动,保障企业网络安全和资源管理。
342 5
|
8月前
|
XML Java 应用服务中间件
SpringBoot-打包&部署
SpringBoot 项目支持两种打包方式:WAR 包和 JAR 包。JAR 包内置 Tomcat,可直接运行;WAR 包需部署在外部 Tomcat 上。JAR 包通过 `mvn clean package` 打包并用 `java -jar` 运行,支持后台运行和 JVM 参数配置。WAR 包需修改 pom.xml 为 war 类型,移除嵌入式 Tomcat 依赖,添加 servlet-api,并继承 `SpringBootServletInitializer`。配置文件可通过外部 application.yml 覆盖,默认优先级高于 JAR 内部配置。
618 17
SpringBoot-打包&部署
|
11月前
|
网络协议 安全 网络性能优化
OSPF中的Totally Not-So-Stubby Area (Totally NSSA):概念、配置与应用
OSPF中的Totally Not-So-Stubby Area (Totally NSSA):概念、配置与应用
272 3
vue-element-admin—登录页面添加自定义背景
vue-element-admin—登录页面添加自定义背景
685 0
|
6月前
|
SQL Java 编译器
深入理解 Spring Data JPA 的导入与使用:以 UserRepository为例
本文深入解析了 Spring Data JPA 中 `UserRepository` 的导入与使用。通过示例代码,详细说明了为何需要导入 `User` 实体类、`JpaRepository` 接口及 `@Repository` 注解。这些导入语句分别用于定义操作实体、提供数据库交互方法和标识数据访问组件。文章还探讨了未导入时的编译问题,并展示了实际应用场景,如用户保存、查询与删除操作。合理使用导入语句,可让代码更简洁高效,充分发挥 Spring Data JPA 的优势。
399 0
|
消息中间件 前端开发 JavaScript
|
安全 Java 测试技术
谈谈springboot的单例模式
【4月更文挑战第13天】在 Spring Boot 和更广泛的 Spring 框架中,单例模式扮演着核心的角色,特别是在 Spring 的 Bean 生命周期和管理中。这里我们详细探讨一下 Spring Boot 中单例模式的运作原理、优势及其潜在问题。
468 7
|
XML Java 数据库连接
springboot中整合mybatis及简单使用
这篇文章介绍了如何在Spring Boot项目中整合MyBatis,包括依赖引入、配置数据源、创建测试表、编写Mapper接口和XML文件、以及创建Service和Controller层的步骤。
springboot中整合mybatis及简单使用
Vscode设置标签页多行显示
这篇文章提供了在VSCode中设置标签页多行显示的方法,以提高编辑效率。
Vscode设置标签页多行显示
|
存储 算法 Java
二分查找(Java) 详细讲解 一文足矣
二分查找(Java) 详细讲解 一文足矣