【Java核心知识】线程基础知识

文章目录

  • 线程
    • 线程与进程的区别
    • 创建线程的方法
      • 方法一:继承Thread类
      • 方法二:实现Runnable接口
      • 方法三:使用Callable和FutureTask创建带返回值的线程
      • 方法四:通过线程池创建线程
    • 线程的基本操作
      • 线程的状态
      • 守护线程

线程

线程与进程的区别

一个进程由程序段数据段进程控制块三部分组成。程序段也称为代码段,是进程的程序指令;数据段是进程的操作数据在内存中的位置;进程控制端(PCB)包含进程的描述信息(如进程ID和进程名称,进程状态。进程优先级)、控制信息(如程序起始地址)、资源信息(内存信息,设备信息,文件句柄)、进程上下文(CPU寄存器的值、程序计数器PC的值),是进程存在的唯一标识

各个进程之间不共享内存,但是线程之间会共享进程的方法区内存空间、堆内存、系统资源。

进程是操作系统分配资源的最小单位,线程CPU调度的最小单位。

每一个线程都有自己独立的栈内存JDK1.8默认是1MB栈内存和堆内存是不一样的,栈内存不会被GC回收。栈内存分配的基本单位是栈帧,线程每进入一个方法,就会分配一个栈帧,栈帧保存着方法中的局部变量、方法的返回值以及方法的其他信息。当方法退出后,栈内存就会弹出该栈帧,进而释放内存空间。

创建线程的方法

方法一:继承Thread类

  • 继承Thread类,创建一个新的线程类,同时重写run方法。

  • 实例化该类,调用start方法启动线程

public class MyThread extends Thread{//线程的编号static int threadNo = 1;public MyThread() {super("DemoThread-" + threadNo++);}public void run() {for (int i = 1; i < 2; i++) {System.out.println(getName() + "轮次" + i);}System.out.println(getName() + "运行结束");}
}
@Test
public void testCreateThread() throws InterruptedException {Thread thread = null;//方法一:使用Thread子类创建和启动线程for (int i = 0; i < 2; i++) {thread = new MyThread();thread.start();}Thread.sleep(3000);System.out.println(Thread.currentThread().getName() + " 运行结束.");
}

方法二:实现Runnable接口

  • 新建类实现Runnable接口
  • 将实现Runnable接口的类传入Thread类中,作为Thread类的目标方法
public class Thread2 implements Runnable{@Overridepublic void run() {System.out.println("我是通过实现Runnable接口创建的线程");}
}
@Test
public void testThread2() throws InterruptedException {Thread thread = new Thread(new Thread2(), "线程2");thread.start();Thread.sleep(1000);
}

或者可以直接传入Runnable接口匿名实现类,还可以使用lambda表达式

@Test
public void testThread2() throws InterruptedException {// Thread thread = new Thread(new Thread2(), "线程2");// 使用lambda表达式// Thread thread = new Thread(() -> System.out.println("我是匿名实现类"));Thread thread = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("我是匿名实现类");}});thread.start();Thread.sleep(1000);
}

如果使用第一种方法创建线程,创建线程时需要new Thread,如果采用继承方法,那么每个线程的数量都是各自享有的,不能共同合作;如果采用实现Runnable接口,创建线程时,可以多个线程共享一个Runnable接口实例,从而多个线程共享数据,相互合作。

实现Runnable接口的方法本质上是Thread的run方法源码会判断自己的target域是否为null,如果不为空,则执行target.run()方法,而target域就是我们传入的Runnable接口实例

方法三:使用Callable和FutureTask创建带返回值的线程

前面实现Runnable接口不能有返回值,如果新的线程需要有返回值,需要实现Callable接口。但是Callable接口跟Runnable接口没什么关系,所以不能作为new Thread(Runnable run)的传入参数。所以为了桥接Callable接口和Runnable接口,定义了一个新的接口RunnableFuture接口,该接口继承了Runnable接口使其可以作为Thread类的传入参数)和Future<>接口(1、取消异步任务,2、判断任务是否执行完毕,3、返回异步任务执行结果)。

FutureTask类实现了RunnableFuture接口,可以作为Thread的传入参数,同时他又拥有一个callable实例,用来执行任务。FutureTask内部还有另一个非常重要的Object 类型的成员——outcome实例属性,用来保存返回结果。

所以整个执行流程为:

  • 首先为了声明一个异步任务,我们需要实现Callable接口的call方法,这是第一步,声明了任务。

  • 可是如何新建线程执行该任务呢?Callable接口实现类并不能作为Thread的target;于是我们把实现Callable接口的任务类传递给了FutureTask类,FutureTask实现了RunnableFuture接口,该接口继承了Runnable和Future接口,可以作为Thread类的target。

从直觉上讲,RunnableCallable接口的地位一致,Future接口是为了管理Callable接口返回值锁增加的功能增强接口,它们两个总是成对出现。关系如下:

在这里插入图片描述

@Test
public void testThread3() throws ExecutionException, InterruptedException {// 将Callable接口实例传入FutureTask类FutureTask<Long> futureTask = new FutureTask<>(() -> {long startTime = System.currentTimeMillis();System.out.println(Thread.currentThread().getName() + " 线程运行开始.");Thread.sleep(1000);for (int i = 0; i < 200; i++) {int j = i * 10000;}long used = System.currentTimeMillis() - startTime;return used;});Thread thread = new Thread(futureTask);thread.start();// 等子线程执行完毕后返回Long res = futureTask.get();System.out.println(res);
}

如果子线程没执行完毕,主线程就调用get()函数获取执行结果,那么主线程会阻塞直到子线程执行完毕

方法四:通过线程池创建线程

可以将一个Runnable接口匿名类或者一个Callable接口匿名类提交给线程池对象来创建线程。

线程池对象由线程池工厂创建。

  • execute方法不带返回值
  • submit方法带返回值:可以看到submit()方法只需要传入Callable接口,不需要创建FutureTask对象,这是因为submit方法内部会创建FutureTask对象。
@Test
public void testExecutor() throws ExecutionException, InterruptedException {ExecutorService executorService = Executors.newCachedThreadPool();// 通过execute方法向线程池提交一个runnable接口匿名类,不带返回值executorService.execute(() -> {System.out.println("我是Runnable接口线程");});Future<Integer> future = executorService.submit(() -> {System.out.println("我是Callable或者Runnable接口线程");return 2;});// 获取返回结果System.out.println(future.get());
}

线程的基本操作

  • Thread.sleep():使线程睡眠,从运行态转为阻塞态
  • Thread.interrupt():将线程的interrupt标志设为true,可以通过isInterrupt()方法判断是否中断。interrupt()方法只是会改变线程中断状态,不会真正中断一个线程,仍需要用户调用isInterrupted()方法进行监控后处理。
  • Thread.join():join()方法是实例方法,需要使用被合并线程的句柄(或者指针、变量)去调用, 主线程必须等待被合并线程执行完毕后才能继续执行
  • Thread.yield():让线程由运行态转为就绪状态,并不会阻塞该线程

线程的状态

  • 新建:新建状态
  • 就绪:等待线程调度
  • 运行:运行中
  • 阻塞:不满足某种条件,被挂起
  • 结束:线程结束

守护线程

  • 守护线程必须在调用start方法前设置
  • 当main函数退出后,守护线程也会退出。如果JVM进程终止,守护线程也会被强制关闭
  • 守护线程创建的线程也是守护线程

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

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

相关文章

解决:burpsuite——Connection refused: no further information

出现该问题的原因是开启了SOCKS proxy&#xff1b;关闭该选项即可正常抓包。 具体操作&#xff1a;

pytest---添加自定义命令行参数(pytest_addoption )

前言 在目前互联网公司中&#xff0c;都会存在多个测试环境&#xff0c;那么当我们编写的自动化想要在多套测试环境下进行运行时&#xff0c;如何使用&#xff1f;大多数人想到的可能是通过将我们自动化代码中的地址修改成不同环境&#xff0c;但是这时候就会增加一些工作量&am…

低成本32位单片机电动工具无感方波控制方案

RAMSUN介绍基于灵动32位微处理器MM32SPIN0230的BLDC电动工具无感方波控制方案&#xff0c;包括MM32SPIN0230芯片资源。 以下是电动工具无感方波控制方案的简述&#xff1a; MM32SPIN0230电动工具专用板 芯片介绍 MM32SPIN0230系列是灵动微MindSPIN旗下高性能的单电机控制产品…

打破对ChatGPT的依赖以及如何应对ChatGPT的错误和幻觉

​ OpenAI的ChatGPT是第一个真正流行的生成式AI工具&#xff0c;但它可能不是最好的。现在是时候扩大你的AI视野了。 ChatGPT成为了基于大语言模型(LLM)的聊天机器人的同义词。但是现在是时候停止对ChatGPT的痴迷&#xff0c;开始发现这个新世界中强大的替代品了。 首先&a…

【BUG事务内消息发送】事务内消息发送,事务还未结束,消息发送已被消费,查无数据怎么解决?

问题描述 在一个事务内完成插入操作&#xff0c;通过MQ异步通知其他微服务进行事件处理。 由于是在事务内发送&#xff0c;其他服务消费消息&#xff0c;查询数据时还不存在如何解决呢&#xff1f; 解决方案 通过spring-tx包的TransactionSynchronizationManager事务管理器解…

基于YOLO v5的病虫害检测与优化

《A fast and lightweight detection algorithm for passion fruit pests based on improved YOLOv5》 a new point-line distance loss function is proposed to reduce redundant computations and shorten detection timethe attention module is added to the network for…

K8S容器OOM killed排查

背景 数据服务平台南海容器k8s设置的内存上限2GB&#xff0c;多次容器被OOM killed。 启动命令 java -XX:MaxRAMPercentage70.0 -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/apps/logs/ ***.jar排查过程 1 当收到实例内存超过95%告警时&#xff0c;把jvm进程堆dump下…

MongoDB入门

简介 MongoDB是一个开源、高性能、支持海量数据存储的文档型数据库 是NoSQL数据库产品中的一种&#xff0c;是最像关系型数据库&#xff08;MySQL&#xff09;的非关系型数据库 内部采用BSON(二进制JSON)格式来存储数据,并支持水平扩展。 MongoDB本身并不是完全免费的,它对于…

Go map转json

在Go中如何返回前端 字段名称/数量都不确定的json数据&#xff1f; 之前用Go写web服务&#xff0c;返回给前端的json格式的接口&#xff0c;有哪些要返回的字段都是明确的。都是预先定义一个结构体&#xff0c;json.Marshal一下即可~ 但当有的场景&#xff0c;要返回哪些字段不…

自动驾驶——【规划】记忆泊车特殊学习路径拟合

1.Back ground 如上图&#xff0c;SLAM学习路线Start到End路径&#xff0c;其中曲线SDAB为D档位学习路径&#xff0c;曲线BC为R学习路径&#xff0c;曲线AE为前进档D档学习路径。 为了使其使用记忆泊车时&#xff0c;其驾驶员体验感好&#xff0c;需去除R档倒车部分轨迹&#x…

2023最新 Electron.js 桌面应用开发教程(基础篇)更新中

Electron是什么&#xff1f; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux Electron Fiddle 运行实例 Ele…

在CAD中批量测量线段的长度

我们经常会有批量测量线段长度的需求&#xff0c;但是线段太多了&#xff0c;一个个加属实浪费时间。网上对这方面也只是个别晦涩的解决方法&#xff0c;大部分无法实用&#xff0c;本文介绍了笔者认为一种最轻松的测量办法。 下图即我们需要测量的线段组&#xff0c;正常测肯定…

python后端,一个账户,多设备登录管理

一个账号&#xff0c;多台设备同时登陆的问题&#xff0c;设计以及实现 参考这篇文章&#xff1a; https://www.alibabacloud.com/help/zh/tair/use-cases/manage-multi-device-logon-from-a-single-user-by-using-tairhash1.0 设计思路 利用的是Redis&#xff0c;主设备的保…

CAD图纸加密软件——公司核心文件数据防泄密「天锐绿盾」

PC访问地址&#xff1a; isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 数据安全保护系统 数据安全保护系统以全面数据文件安全策略、加解密技术与强制访问控制有机结合为设计思想&#xff0c;对信息媒介上的各种数据资产&#xff0c;实施不同安全等级…

02_nodejs开发环境安装

02 【nodejs开发环境安装】 1.版本介绍 在命令窗口中输入 node -v 可以查看版本0.x 完全不技术 ES64.x 部分支持 ES6 特性5.x 部分支持ES6特性&#xff08;比4.x多些&#xff09;&#xff0c;属于过渡产品&#xff0c;现在来说应该没有什么理由去用这个了6.x 支持98%的 ES6 特…

jvm 新生代的区域划分

虚拟机将内存分为一块较大的 Eden 空间和两块较小的 Survivor 空间&#xff0c;每次分配内存只使用 Eden 和其中一块 Survivor。发生垃圾收集时&#xff0c;将 Eden 和 Survivor 中仍然存活的对象一次性复制到另外一块 Survivor 空间上&#xff0c;然后直接清理掉 Eden 和已用过…

耐蚀点蚀镀铜工艺

引言 随着5G技术的推出&#xff0c;导致电子电路和IC基板在设计中要求更高的密度。由于5G应用的性质&#xff0c;这些设计中的高可靠性和出色的电气性能也越来越重要。为了满足5G应用和其他下一代设备平台的需求&#xff0c;逐渐建立了使用改良半加成加工(mSAP)制造电路板的制…

安达发|生产计划排程APS系统整体结构引领企业智能化生产

随着科技的不断发展&#xff0c;企业对于生产计划排程的需求也在不断提高。在过去的生产计划管理中&#xff0c;企业往往需要根据销售订单或销售报表来分配生产加工任务&#xff0c;这种方式容易导致生产加工不均衡&#xff0c;影响企业的竞争力。为了解决这一问题&#xff0c;…

对ioc的简单理解

最近闲着无聊&#xff0c;又把ioc梳理了一遍&#xff0c;一边看一边满脑子是王宝强的“啥啥啥&#xff0c;这又是个啥”的表情包。 一会注入、一会依赖、一会又自动装配的……哎……还好有了点头绪。 ioc的概念 1、ioc是什么&#xff1f;有什么用&#xff1f; 老生常谈&…

设计模式备忘录+命令模式实现Word撤销恢复操作

文章目录 前言思路代码实现uml类图总结 前言 最近学习设计模式行为型的模式&#xff0c;学到了备忘录模式提到这个模式可以记录一个对象的状态属性值&#xff0c;用于下次复用&#xff0c;于是便想到了我们在Windows系统上使用的撤销操作&#xff0c;于是便想着使用这个模式进…