java多线程一

1、什么是线程

        线程(Thread)是一条程序内部的一条执行流程。

        程序中如果只有一条执行流程,那这个程序就是单线程的程序。

2、什么是多线程

        多线程(multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理或同时多线程处理器。在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理“。

3、多线程的优缺点

3.1、优点

  • 同时执行多个任务,提高程序的工作效率。
  • 提高CPU的使用率。
  • 线程之间可以共享资源。
  • 相比进程而言,创建线程代价比较小。

 3.2、缺点

  • 等候使用共享资源时造成程序的运行速度变慢。这些共享资源主要是独占性的资源 ,如打印机等。
  • 对线程进行管理要求额外的 CPU开销,线程的使用会给系统带来上下文切换的额外负担
  • 可能会出现线程的死锁。即对共享资源加锁实现同步的过程中可能会死锁。

 4、java中的多线程

        在java语言中: 线程A和线程B,堆内存和方法区内存共享。 但是栈内存独立,一个线程一个栈。假设启动10个线程,会有10个栈空间,每个栈和每个栈之间,互不干扰,各自执行各自的,这就是多线程并发。

5.、java多线程的声明周期

  • 创建(New):线程对象通过 new 关键字创建,但还未调用 start() 方法时,线程处于新建状态。此时,线程对象已经分配了内存空间,但尚未启动执行。
  • 就绪(Runnable):线程对象调用 start() 方法后,线程处于就绪状态。此时,线程已经准备好执行,但还没有获得 CPU 时间片。多个线程处于就绪状态时,由 Java 虚拟机的线程调度器来决定哪个线程获得 CPU 时间片开始执行。
  • 运行(Running):当线程获得 CPU 时间片开始执行时,线程处于运行状态。此时,线程的 run() 方法正在被执行。
  • 阻塞(Blocked):在特定情况下,线程可能会被暂时挂起,进入阻塞状态。例如,线程调用了 sleep() 方法、等待 I/O 操作、获得了某个对象的锁但没有获取到锁等。当阻塞状态的条件解除时,线程会重新进入就绪状态,等待获取 CPU 时间片继续执行。
  • 销毁(Terminated):线程执行完 run() 方法后,或者调用了 stop() 方法,线程将进入销毁状态。一旦线程进入了销毁状态,就无法再恢复到其他状态。

 6、Java中多线程的实现方式

6.1、继承Thread类

  1. 定义一个类继承Thread类,重写run方法
  2. 创建调用线程类的对象
  3. 调用线程对象的start方法启动线程(启动后会自动执行MyThread中重写的run()方法)
/***  1、类继承Thread类**/
public class ThreadTest extends Thread{//必须重写Thread类中的run方法@Overridepublic void run() {//super.run();for (int i = 0; i <= 5; i++) {System.out.println("子线程:"+i);}}
}public class ThreadMain {public static void main(String[] args) {//2、创建子线程对象Thread t = new ThreadTest();//3、启动子线程t.start();for (int i = 0; i <= 5; i++) {System.out.println("主线程:"+i);}}
}

PS:

  1. 该方法编码简单,但使用了继承,不利于扩展。
  2. 启动线程必须是用start方法,不能用run方法,否知会变成单线程。
  3. 不要把主线程任务放到启动子线程之前,否则会变成成主线程执行完了,才执行子线程。

6.2、实现Runnable接口

  1. 定义一个线程任务类MyRunnable实现Runnable接口,重写run方法
  2. 创建MyRunnable对象
  3. 把MyRunnable对象交给Thread处理  
/*** 1、实现Runnable接口**/
public class RunnableTest implements Runnable{//重现run方法@Overridepublic void run() {for (int i = 0; i <= 5; i++) {System.out.println("子线程:"+i);}}
}public class RunnableMain {public static void main(String[] args) {/*** 2.创建子线程对象*/Runnable target = new RunnableTest();/*** 3.把Runnable对象交给Thread处理*/Thread t = new Thread(target);t.start();for (int i = 0; i < 5; i++) {System.out.println("主线程执行输出" + i);}}
}

PS:实现接口,可以继续继承或者实现接口,扩展性强

 匿名内部类(推荐方法)

public class RunnableMain1 {public static void main(String[] args) {//简化方式一Runnable r = new Runnable() {@Overridepublic void run() {for (int i = 0; i <= 5; i++) {System.out.println("子线程1:"+i);}}};new Thread(r).start();//简化方式二new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <= 5; i++) {System.out.println("子线程2:"+i);}}}).start();//简化方式三(lambda表达式)(jdk8以上)new Thread(() -> {for (int i = 0; i <= 5; i++) {System.out.println("子线程3:"+i);}}).start();for (int i = 0; i < 5; i++) {System.out.println("主线程执行输出" + i);}}
}

6.3、实现Callable接口,通过FutureTask接口接收返回值(JDK5新增)

  1. 得到任务对象 第一步:定义一个线程任务类MyCallable实现Callable接口,重写call方法,该方法可以返回结果 第二步:用Future吧Callable对象封装成线程任务对象
  2. 把线程任务对象交给Thread处理
  3. 调用Thread的start方法启动任务
  4. 线程执行完毕后,通过FutureTask的get方法获得结果 
/***  1、定义一个实现类,实现Callable接口,记得声明结果的数据类型**/
public class CallableTest implements Callable<String> {//2.重写call方法private int n;public CallableTest(int n) {this.n = n;}@Overridepublic String call() throws Exception {int sum = 0;for (int i = 1; i <= n; i++) {sum += i;}return "子线程执行的结果是" + sum;}
}public class CalableMain {public static void main(String[] args) {//3.创建任务对象Callable<String> call1 = new CallableTest(100);/*** 4.把Callable任务对象交给FutureTask对象* FutureTask的作用1:FutureTask实现了Runnable接口,此时就可以交给Thread了* FutureTask的作用2:可以在线程执行完毕后调用get方法得到线程执行的结果*///Thread t = new Thread(call);  报错,Thread不能接收call对象FutureTask<String> f1 = new FutureTask<>(call1);//5.交给线程处理Thread t1 = new Thread(f1);//6.启动线程t1.start();Callable<String> call2 = new CallableTest(200);FutureTask<String> f2 = new FutureTask<>(call2);Thread t2 = new Thread(f2);t2.start();try {String rs1 = f1.get();   //直接调用call方法,可能还没有执行完,使用get时若发现线程未执行完会先等线程执行完毕System.out.println("第一个结果为:" + rs1);} catch (Exception e) {e.printStackTrace();}try {String rs2 = f2.get();   //直接调用call方法,可能还没有执行完,使用get时若发现线程未执行完会先等线程执行完毕System.out.println("第二个结果为:" + rs2);} catch (Exception e) {e.printStackTrace();}}
}

PS:

  • 扩展性强,可以继续继承和实现。
  • 可以在线程执行完毕后获取线程执行的结果。

6.4、Thread常用方法和构造器

Thread提供的常用方法说明
public void run()线程的任务方法
public void start()启动线程
jublic String getName()获取当前线程的名称,线程名称默认是Thread-索引
public void setName(String name)为线程设置名称
public static Thread currentThread()获取当前执行的线程对象
public static void sleep(long time)让当前执行的线程休眠多少毫秒后,再继续执行
public final void join()...让调用当前这个放的线程先执行完
Thread提供的常见构造器说明
public Thread(String name)可以为当前线程指定名称
public Thread(Runnable target)封装Runnable对象成为线程对象
public Thread(Runnable target,String name)封装Runnable对象成为线程对象,并指定线程名称

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

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

相关文章

【SAS Planet 下载地图瓦片-读取】

SAS Planet下载地图瓦片请看上一篇 详细介绍了下载方法 【SAS Planet 下载地图瓦片】-CSDN博客 准备工作&#xff1a; 1.提前下载好地图瓦片数据 SAS Planet下载地图瓦片默认存储路径如下 默认存储格式为 .sqlitedb 2.提前准备好 java开发环境和开发工具&#xff0c;新建 一个…

安卓吸顶效果

当列表滑动时&#xff0c;图片逐渐消失&#xff0c;toolBar悬停在头部。 <?xml version"1.0" encoding"utf-8"?><androidx.coordinatorlayout.widget.CoordinatorLayoutxmlns:android"http://schemas.android.com/apk/res/android"x…

网络运维与网络安全 学习笔记2023.11.26

网络运维与网络安全 学习笔记 第二十七天 今日目标 NAT场景与原理、静态NAT、动态NAT PAT原理与配置、动态PAT之EasyIP、静态PAT之NAT Server NAT场景与原理 项目背景 为节省IP地址和费用&#xff0c;企业内网使用的都是“私有IP地址” Internet网络的组成设备&#xff0c…

Python自动化测试学习路线【进阶必看】

软件自动化测试的学习步骤 大概步骤如下&#xff1a; 1. 做好手工测试&#xff08;了解各种测试的知识&#xff09;-> 2. 学习编程语言-> 3. 学习Web基础&#xff08;HTML,HTTP,CSS,DOM,Javascript&#xff09;或者 学习Winform -> 4. 学习自动化测试工具 ->5.…

Cisco Packet Tracer配置命令——路由器篇

路由基础 路由器用于互联两个或多个网络&#xff0c;具有两项功能&#xff1a;为要转发的数据包选择最佳路径以及将数据包交换到正确的端口&#xff0c;概括为路由选择和分组转发。 路由选择 路由选择就是路由器根据目的IP地址的网络地址部分&#xff0c;通过路由选择算法确…

公司人事管理系统

1.问题描述 一个小公司包含四类人员&#xff1a;经理&#xff0c;技术人员&#xff0c;销售人员和销售经理&#xff0c;各类人员的工资计算方法如下&#xff1a;经理&#xff1a;固定月薪&#xff08;8000&#xff09;&#xff1b;技术人员&#xff1a;月薪按技术等级&#xf…

类与对象——(1)初识对象——C++中的string

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 或许不安或许迷惑&#xff0c;但…

Factory 工厂模式-C语言实现

说明&#xff1a; 均由 chatgpt生成&#xff0c;实例可以看出无法运行&#xff0c;仅供参考~ UML图&#xff1a; ‘ 表示public, - 表示private,“# 表示protected.” 一文掌握14种UML图-腾讯云开发者社区-腾讯云 (tencent.com) 五分钟带你读懂UML类图 - 知乎 (zhihu.com)…

SpringBoot 环境使用 Redis + AOP + 自定义注解实现接口幂等性

目录 一、前言二、主流实现方案介绍2.1、前端按钮做加载状态限制&#xff08;必备&#xff09;2.2、客户端使用唯一标识符2.3、服务端通过检测请求参数进行幂等校验&#xff08;本文使用&#xff09; 三、代码实现3.1、POM3.2、application.yml3.3、Redis配置类3.4、自定义注解…

U-boot(五):启动内核

本文主要探讨210的uboot启动内核过程。 嵌入式系统状态启动 未上电时bootloader、kernel、rootfs以镜像形式存储在启动介质中(X210为iNand/SD卡),运行时搬运到DDR中 未上电时u-boot.bin,zImage,rootfs在SD卡中各自对应的分区中,启动时去对应分区寻找(分区表一…

【Java】实现一个自己的定时器

上文讲了怎样使用Java自带的定时器【Java】定时器的简单应用 这篇博客就来讲如何来编写一个自己实现的定时器 1、代码框架 由定时器的使用方法得知&#xff0c;我们在使用定时器的时候会添加一个任务timerTask类&#xff0c;而timer类则是我们行使任务的类&#xff0c;因此可…

【Apache Doris】Manager极致丝滑地运维管理

【Apache Doris】Manager极致丝滑地运维管理 1.标准VS可视化运维管理2. 环境信息2.1.硬件信息2.2.软件信息 3.前置准备3.1.安装包准备3.2.文档手册准备 4.集群初始化4.1.系统参数预设4.2.Manager部署4.3.新集群部署4.4 监控告警4.4.1 监控4.4.2 告警 5. 集群升级5.1 新包准备5.…

人力资源管理后台 === 登陆+主页鉴权

目录 1. 分析登录流程 2. Vuex中用户模块的实现 3.Vue-cli代理解决跨域 4.axios封装 5.环境区分 6. 登录联调 7.主页权限验证-鉴权 1. 分析登录流程 传统思路都是登录校验通过之后&#xff0c;直接调用接口&#xff0c;获取token之后&#xff0c;跳转到主页。 vue-elemen…

【数据库基础】

目录&#xff1a; 前言什么是数据库主流数据库服务器&#xff0c;数据库&#xff0c;表关系MySQL架构SQL分类存储引擎 前言 剑指offer&#xff1a;一年又1天 什么是数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 文件保存数据有以下几个缺点&#xff1a;…

大量索引场景下 Easysearch 和 Elasticsearch 的吞吐量差异

最近有客户在使用 Elasticsearch 搜索服务时发现集群有掉节点&#xff0c;并且有 master 收集节点信息超时的日志&#xff0c;节点的负载也很高&#xff0c;不只是 data 节点&#xff0c;master 和协调节点的 cpu 使用率都很高&#xff0c;看现象集群似乎遇到了性能瓶颈。 查看…

算法设计与分析(贪心法)

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

中国一年有457万人确诊癌症!医生提示:这4种食物,再爱吃也要管住嘴

癌症是威胁人类生命健康的重大疾病&#xff0c;癌症的发生因素一直以来都是专家学者重点探索的课题。据世卫组织最新公布的数据显示&#xff0c;食物或与癌症发生之间存在着密切的联系&#xff0c;某些食物的摄入过多可能会增加患癌症的风险&#xff0c;所以我们应该警惕&#…

IDEA中JDK21控制台打印的中文乱码

IDEA中&#xff0c;使用的JDK21&#xff0c;控制台打印中文乱码&#xff0c;解决办法是重装了一下JDK。 我之前安装的版本是“jdk-21_windows-x64_bin.exe”&#xff0c;我配置了多个JDK环境&#xff0c;所以使用的是安装文件进行安装的。这次解决乱码问题&#xff0c;我重新安…

代码随想录算法训练营第四十八天|121. 买卖股票的最佳时机、122. 买卖股票的最佳时机 II

LeetCode 121. 买卖股票的最佳时机 题目链接&#xff1a;121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; 直觉告诉我要贪心算法&#xff0c;章节告诉我得用DP来做&#xff0c;行&#xff0c;都做一下&#xff01; 贪心&#xff1a;只能买一次&#xff0c;所…

Vatee万腾的科技冒险:Vatee独特探索力量的数字化征程

在数字化时代的激流中&#xff0c;Vatee万腾以其独特的科技冒险精神&#xff0c;引领着一场前所未有的数字化征程。这不仅仅是一次冒险&#xff0c;更是对未知的深度探索&#xff0c;将科技的力量推向新的高度。 Vatee万腾在科技领域敢于挑战传统&#xff0c;积极探索未知的可能…