【线程创建】——三种方式➕多线程案例练习

02 线程创建

Thread , Runnable , Callable

三种创建方式

Thread class - 继承Thread类 (重点)

Runnable接口 - 实现Runnable接口 (重点)

Callable接口 - 实现Callable接口 (了解)

Thread 类实现

它继承了老祖宗 Object
java.lang.Object
java.lang.Thread

它实现了 Runnable接口

线程是程序中执行的线程. Java虚拟机允许应用程序同时执行多个执行线程.

每个线程都有优先权. 就是你的优先权更高你先执行, 你的优先权低你就后执行, 还有守护线程, 和用户线程, 这个地方先不聊, 本章主要讲如何创建线程

创建一个新的线程有两种方法, 一个是将一个类声明为Thread的子类, 这个子类应该重新run类的方法Thread. 然后可以分配并启动子类的实例. 例如, 计算大于规定值的素数的线程可以写成如下:

  • 自定义线程类继承**Thread类**
  • 重写**run()**方法
  • 创建线程对象, 调用**start()**方法启动线程
继承Thread类实现

我们下面用代码实现一下:

package com.jean.thread;//创建线程方式一: 继承Thread类, 重写run()方法, 调用start开启线程
public class TestThread1 extends Thread {//    继承完, 立即重写run方法@Overridepublic void run() {
//        run方法线程体for (int i = 0; i < 20; i++) {System.out.println("我在看代码----"+i);}}public static void main(String[] args) {
//        main线程, 主线程for (int i = 0; i < 20; i++) {System.out.println("我在学习多线程----"+i);}}
}

我们执行后, 控制台加载完后就一瞬间输出了20个我在学习多线程, 我们如果想把另一个线程开启怎么开呢?

package com.jean.thread;//创建线程方式一: 继承Thread类, 重写run()方法, 调用start开启线程
public class TestThread1 extends Thread {//    继承完, 立即重写run方法@Overridepublic void run() {
//        run方法线程体for (int i = 0; i < 20; i++) {System.out.println("我在看代码----"+i);}}public static void main(String[] args) {
//        main线程, 主线程//        首先创建它的一个对象TestThread1 testThread1 = new TestThread1();
//        调用start方法, 开启线程testThread1.start();for (int i = 0; i < 20; i++) {System.out.println("我在学习多线程----"+i);}}
}

在这里插入图片描述

我们调用了start方法后, 控制台明显执行的先后顺序就随机了, 所以说

调用start()方法是同时来运行的, 交替执行

我们的多线程调用了一个start方法, 它直接走下来进了start方法, 他开辟了一条新的线程, 它去执行它的方法, 主线程依据去走主线程的

然后我们再改调用run()方法

package com.jean.thread;//创建线程方式一: 继承Thread类, 重写run()方法, 调用start开启线程
public class TestThread1 extends Thread {//    继承完, 立即重写run方法@Overridepublic void run() {
//        run方法线程体for (int i = 0; i < 20; i++) {System.out.println("我在看代码----"+i);}}public static void main(String[] args) {
//        main线程, 主线程//        首先创建它的一个对象TestThread1 testThread1 = new TestThread1();
//        调用run方法, 开启线程testThread1.run();for (int i = 0; i < 20; i++) {System.out.println("我在学习多线程----"+i);}}
}

在这里插入图片描述
使用run方法调用, 他先走run方法, 执行完了才去执行主路径

总结:

线程开启不一定立即执行, 由CPU调度安排

多线程网图下载

案例: 下载图片

使用多线程同时去下载几个图片

  1. 先引入一下jar包 Commons IO包.

可以直接去百度搜索Commons IO , 是Apache下的.

  • Commons IO是针对开发IO流功能的工具类库.

  • FileUtils文件工具, 复制url到文件

Commons-io包的下载地址
在这里插入图片描述
点击图中红色圈起来的jar链接即可实现下载

创建lib文件, 把lib目录添加为库.

  1. 创建lib文件
  2. 点击lib文件获取焦点, 右键点击
  3. 选择添加为库
  4. 添加为jar
    在这里插入图片描述
    添加成功之后, 文件前会有一个箭头

新建TestDownload文件

package com.jean.thread;import org.apache.commons.io.FileUtils;import java.io.File;
import java.io.IOException;
import java.net.URL;/*** @BelongsProject: Thread-class01* @BelongsPackage: com.jean.thread* @Author: Jean_z* @CreateTime: 2024-05-13  08:31* @Description: TODO: 练习Thread, 实现多线程同步下载图片* @Version: 1.0*/
public class TestDownload implements Runnable{private String url; //网络图片地址private String name; //保存的文件名//    构造器public TestDownload(String url, String name) {this.url = url;this.name = name;}//    下载图片线程的执行体@Overridepublic void run() {WebDownload webDownload = new WebDownload();webDownload.download(url,name);System.out.println("下载了文件名为:" + name);}//    启动线程public static void main(String[] args) {TestDownload testDownload1 = new TestDownload("https://img-home.csdnimg.cn/images/20240511083237.png", "我是图片的名字1");TestDownload testDownload2 = new TestDownload("https://img-home.csdnimg.cn/images/20240511083237.png", "我是图片的名字2");TestDownload testDownload3 = new TestDownload("https://img-home.csdnimg.cn/images/20240511083237.png", "我是图片的名字3");//        Thread类方法
//        testDownload1.start();
//        testDownload2.start();
//        testDownload3.start();//        Runnable接口方法new Thread(testDownload1).start();new Thread(testDownload2).start();new Thread(testDownload3).start();}
}// 下载器
class WebDownload {
//    下载方法public void download(String url,String name) {
//        FileUtils: 文件工具
//        copyURLToFile 拷贝url地址到一个文件try {FileUtils.copyURLToFile(new URL(url),new File(name));} catch (IOException e) {e.printStackTrace();System.out.println("IO异常, download 方法出问题了");}}
}

Runnable接口实现多线程.

跟推荐的一种实现多线程的方式: Runnable

创建线程方式2

  1. 实现Runnable接口,
  2. 重写run方法, 执行线程需要丢入runnable接口实现类,调用start方法.
package com.jean.thread;/*** @BelongsProject: Thread-class01* @BelongsPackage: com.jean.thread* @Author: Jean_z* @CreateTime: 2024-05-13  09:38* @Description: TODO* @Version: 1.0*///创建线程方式2 : 实现Runnable接口, 重写run方法, 执行线程需要丢入runnable接口实现类,调用start方法.
public class TestRunnable implements Runnable{//    继承完, 立即重写run方法@Overridepublic void run() {
//        run方法线程体for (int i = 0; i < 20; i++) {System.out.println("我在看代码----"+i);}}public static void main(String[] args) {
//        main线程, 主线程
//        创建runnable接口的实现对象TestRunnable runnable = new TestRunnable();//        创建线程对象, 通过线程对象来开启我们的线程, 代理
//        Thread thread = new Thread(runnable);
//        调用start方法, 开启线程new Thread(runnable).start();for (int i = 0; i < 2000; i++) {System.out.println("我在学习多线程----"+i);}}
}

Callable 方式 实现多线程

第三种实现多线程的方式: Callable

我们基于多线程下载网络图片代码, 修改.

  1. 实现Callable接口

  2. 重写call方法 类型

  3. 创建执行事务

    ExecutorService executorService = Executors.newFixedThreadPool (3);

  4. 提交执行

  5. 获取执行结果, boolean类型

  6. 关闭服务

之前是重写run方法, 我们这里不一样, 重写的是call方法, 注意方法类型是布尔.

第三种方式, 了解即可 !

package com.jean.thread;import org.apache.commons.io.FileUtils;import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;/*** @BelongsProject: Thread-class01* @BelongsPackage: com.jean.thread* @Author: Jean_z* @CreateTime: 2024-05-13  08:31* @Description: TODO: 练习Thread, 实现多线程同步下载图片* @Version: 1.0*/
public class TestCallable implements Callable<Boolean> {private String url; //网络图片地址private String name; //保存的文件名//    构造器public TestCallable(String url, String name) {this.url = url;this.name = name;}//    下载图片线程的执行体@Overridepublic Boolean call() {WebDownload2 webDownload = new WebDownload2();webDownload.download(url,name);System.out.println("下载了文件名为:" + name);return true;}//    启动线程public static void main(String[] args) throws ExecutionException, InterruptedException {TestCallable testCallable1= new TestCallable("https://img-home.csdnimg.cn/images/20240511083237.png", "我是图片的名字1");TestCallable testCallable2= new TestCallable("https://img-home.csdnimg.cn/images/20240511083237.png", "我是图片的名字2");TestCallable testCallable3= new TestCallable("https://img-home.csdnimg.cn/images/20240511083237.png", "我是图片的名字3");//        Thread类方法
//        testDownload1.start();
//        testDownload2.start();
//        testDownload3.start();//        创建执行事务ExecutorService executorService = Executors.newFixedThreadPool(3);//        提交执行Future<Boolean> r1 = executorService.submit(testCallable1);Future<Boolean> r2 = executorService.submit(testCallable2);Future<Boolean> r3 = executorService.submit(testCallable3);//        获取结果boolean rs1 = r1.get();boolean rs2 = r2.get();boolean rs3 = r3.get();System.out.println(rs1);System.out.println(rs2);System.out.println(rs3);//        关闭服务executorService.shutdownNow();}
}// 下载器
class WebDownload2 {
//    下载方法public void download(String url,String name) {
//        FileUtils: 文件工具
//        copyURLToFile 拷贝url地址到一个文件try {FileUtils.copyURLToFile(new URL(url),new File(name));} catch (IOException e) {e.printStackTrace();System.out.println("IO异常, download 方法出问题了");}}
}

多线程 “龟🐢” “兔🐇” 赛跑案例

案例需求:

  1. 首先先来个赛道距离, 然后要离重点越来越近
  2. 判断比赛是否结束
  3. 打印出胜利者
  4. 龟兔赛跑开始
  5. 故事中是乌龟🐢速度慢但是依旧是乌龟赢的, 兔子🐇需要睡觉, 所以我们来模拟兔子睡觉💤
  6. 终于, 乌龟🐢赢得比赛.
sleep多线程的延时方法

Thread.sleep ( 5000 ) // 这里是毫秒

package com.jean.thread;/*** @BelongsProject: Thread-class01* @BelongsPackage: com.jean.thread* @Author: Jean_z* @CreateTime: 2024-05-13  10:21* @Description: TODO* @Version: 1.0*/
//模拟龟兔赛跑
public class TestRace implements Runnable{//    胜利者private static String winner;
//    private static String winner;@Overridepublic void run() {for (int i = 1; i <= 100; i++) {//            模拟兔子休息if (Thread.currentThread().getName().equals("兔子🐇")) {try {Thread.sleep(30);} catch (InterruptedException e) {e.printStackTrace();System.out.println("兔子🐇喝伏特加了, 无比清醒, 不想睡觉");}}//            模拟乌龟速度if (Thread.currentThread().getName().equals("乌龟🐢")) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}//            判断比赛是否接结束boolean flag = gameOver(i);
//            比赛结束停止程序if (flag) {break;}System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步");}}//    判断是否完成比赛private boolean gameOver(int steps) {
//        判断是否有胜利者if (winner!=null) { //已经存在胜利者了return true;}{if (steps>=100){winner = Thread.currentThread().getName();System.out.println("最终胜利者 is "+winner);return true;}}return false;}//赛道public static void main(String[] args) {TestRace race = new TestRace();new Thread(race,"兔子🐇").start();new Thread(race,"乌龟🐢").start();}}

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

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

相关文章

文本到语音的学习笔记:从Docker开始

1.docker 是什么意思&#xff1f; Docker 是一种开源的容器化平台&#xff0c;它允许开发者将应用及其依赖打包到一个轻量级、可移植的容器中&#xff0c;然后可以在任何支持Docker的系统上运行这个应用&#xff0c;而不必担心环境差异导致的问题。 以下是Docker的一些关键特…

【go项目01_学习记录11】

操作数据库 1 文章列表2 删除文章 1 文章列表 &#xff08;1&#xff09;先保证文章已经有多篇&#xff0c;可以直接在数据库中添加&#xff0c;或者访问链接: localhost:3000/articles/create&#xff0c;增加几篇文章。 &#xff08;2&#xff09;之前设置好了articles.ind…

栈队列经典OJ题(详细过程)

1. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 第一题判断有效的括号&#xff0c;这道题我们会用到栈的知识&#xff0c;栈是后进先出的&#xff0c;可以根据这个来解这道题&#xff0c;先看一下题目和示例。 1.1整体思路 我们通过示例可以看出括号匹配就返回true&am…

【JAVA】BOSS系统发版艺术:构建高效、优雅的微服务部署策略

在现代软件开发领域&#xff0c;微服务架构与容器化部署已迅速成为行业新趋势。微服务架构通过将应用拆分成多个小型、自治的服务单元&#xff0c;每个服务承担某项特定的业务功能。而容器化部署则以其轻量级和高度可移植的特性&#xff0c;为这些微服务的有效打包、分发和运行…

科技查新中的工法查新点如何确立与提炼?案例讲解!

按《工程建设工法管理办法》( 建 质&#xff3b;2014&#xff3d;103 号) &#xff0c;工法&#xff0c;是指以工程为对象&#xff0c;以工艺为核心&#xff0c;运用系 统工程原理&#xff0c;把先进技术和科学管理结合起来&#xff0c;经过一定工程实践形成的综合配套的施工方…

探索美国动态IP池:技术赋能下的网络安全新篇章

在数字化飞速发展的今天&#xff0c;网络安全成为了各行各业关注的焦点。特别是在跨国业务中&#xff0c;如何保障数据的安全传输和合规性成为了企业面临的重要挑战。美国动态IP池作为一种新兴的网络技术&#xff0c;正逐渐走进人们的视野&#xff0c;为网络安全提供新的解决方…

黑马甄选离线数仓项目day02(数据采集)

datax介绍 官网&#xff1a; https://github.com/alibaba/DataX/blob/master/introduction.md DataX 是阿里云 DataWorks数据集成 的开源版本&#xff0c;在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。 DataX 实现了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre…

计算机Java项目|Springboot学生读书笔记共享

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、Python项目、前端项目、人工智能与大数据、简…

华为设备display查看命令

display version //查看版本信息 display current-configuration //查看配置详情 display this //查看当前视图有效配置 display ip routing-table //查看路由表 display ip routing-table 192.168.3.1 //查看去往3.1的路由 display ip interface brief //查看接口下ip信息 dis…

想跨境出海?云手机提供了一种可能性

全球化时代&#xff0c;越来越多的中国电商开始将目光投向了海外市场。这并不是偶然&#xff0c;而是他们在长期的市场运营中&#xff0c;看到了出海的必要性和潜在的机会。 中国的电商市场无疑是全球最大也最发达的之一。然而&#xff0c;随着市场的不断发展和竞争的日益加剧…

visual studio2022 JNI极简开发流程

文章目录 1 创建java类2 生成JNI头文件3 使用visual studio2022创建DLL项目3.1 选择模板中&#xff08;Windows桌面向导&#xff09;3.2 为项目命名3.3 选择应用程序类型为动态链接库3.4 项目概览 4 导入需要的头文件4.1 导入需要的头文件4.2 修改头文件 5 编写C实现6 生成dll文…

服务器3389端口,服务器3389端口风险提示的应对措施

3389端口是Windows操作系统中远程桌面协议&#xff08;RDP&#xff09;的默认端口。一旦该端口被恶意攻击者利用&#xff0c;可能会导致未经授权的远程访问和数据泄露等严重安全问题。 针对此风险&#xff0c;强烈建议您采取以下措施&#xff1a; 1. 修改默认端口&#xff1a;…

springboot3 集成spring-authorization-server (一 基础篇)

官方文档 Spring Authorization Server 环境介绍 java&#xff1a;17 SpringBoot&#xff1a;3.2.0 SpringCloud&#xff1a;2023.0.0 引入maven配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter…

识别AI论文生成内容,降低论文高AI率

AI写作工具能帮我们在短时间内高效生成一篇毕业论文、开通报告、文献综述、任务书、调研报告、期刊论文、课程论文等等&#xff0c;导致许多人开始使用AI写作工具作为撰写学术论文的辅助手段。而学术界为了杜绝此行为&#xff0c;开始使用AIGC检测系统来判断文章是由AI生成还是…

解锁商业AI,赋能新质生产力发展——思爱普中国峰会探展全纪录

ITValue 钛媒体独家探秘思爱普中国峰会&#xff0c;带你深刻感受SAP助力企业利用以商业AI为代表的数字化技术&#xff0c;实现质的飞跃&#xff0c;通过全数据、全球化、全绿色赋能新型中国企业发展新质生产力。 首发&#xff5c;钛媒体APP ITValue 5月10日&#xff0c;一年一度…

基于NTP服务器获取网络时间的实现

文章目录 1 NTP1.1 简介1.2 包结构1.3 UNIX 时间戳和NTP时间戳 2 代码实现2.1 实现步骤2.2 完整代码 3 结果 在某些场景下&#xff0c;单片机需要通过网络获取准确的时间进行数据同步&#xff0c;例如日志记录、定时任务等。然而&#xff0c;单片机本身无法直接获得准确的标准时…

Vue的学习 —— <vue指令>

目录 前言 正文 内容渲染指令 内容渲染指令的使用方法 v-text v-html 属性绑定指令 双向数据绑定指令 事件绑定指令 条件渲染指令 循环列表渲染指令 侦听器 前言 在完成Vue开发环境的搭建后&#xff0c;若想将Vue应用于实际项目&#xff0c;首要任务是学习Vue的基…

ORA-00932: inconsistent datatypes: expected - got CLOB的分析解决方案

最近在项目中遇到查询数据时报ORA-00932: inconsistent datatypes: expected - got CLOB错误&#xff0c;这个错误很明显是由于查询时类型的不匹配造成的。 问题分析&#xff1a; 一、检查你的查询的实体的类型是否于数据库的保持一致&#xff0c;如果不一致&#xff0c;那么需…

[力扣题解] 96. 不同的二叉搜索树

题目&#xff1a;96. 不同的二叉搜索树 思路 动态规划 f[i]&#xff1a;有i个结点有多少种二叉搜索树 状态转移方程&#xff1a; 以n3为例&#xff1a; 以1为头节点&#xff0c;左子树有0个结点&#xff0c;右子树有2个结点&#xff1b; 以2为头节点&#xff0c;左子树有1个…

安科瑞AIM-D100-ES光伏储能系统直流绝缘监测仪

概述 AIM-D100-ES 型直流绝缘监测仪主要用于在线监测直流不接地系统正负极对地绝缘电阻&#xff0c;当绝缘电阻低于设定值时&#xff0c;能发出预警和报警信号。 产品可测 100-1500V 的直流系统&#xff0c;可应用于储能直流系统、电动汽车充电装置、UPS 供电系统、光伏直流系…