Java基础知识-线程

Java基础知识-线程

1、在 Java 中要想实现多线程代码有几种手段?

1.  一种是继承 Thread 类

2.  另一种就是实现 Runnable 接口

3.  最后一种就是实现 Callable 接口

4.  第四种也是实现 callable 接口,只不过有返回值而已

2、Thread 类中的 start() 和 run() 方法有什么区别?

start()方法被用来启动新创建的线程,而且 start()内部调用了 run()方法,这和直接调用 run()方法的效果不一样。当你调用 run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。

3、Java 中 notify 和 notifyAll 有什么区别?

notify()方法不能唤醒某个具体的线程,所以只有一个线程在等待的时候它 才有用武之地。而 notifyAll()唤醒所有线程并允许他们争夺锁确保了至少有一 个线程能继续运行。

4、Java 多线程中调用 wait() 和 sleep()方法有什么不同?

Java 程序中 wait 和 sleep 都会造成某种形式的暂停,它们可以满足不同的需要。wait()方法用于线程间通信,如果等待条件为真且其它线程被唤醒时它会释放锁,而 sleep()方法仅仅释放 CPU 资源或者让当前线程停止执行一段时间,但不会释放锁。

java中,sleep和wait方法都用于线程的暂停,但它们在原理、使用场景、对锁的处理机制等方面有所不同。以下是详细介绍:

● 原理不同。sleep是Thread类中的静态方法,用于让线程暂停执行一段时间,但不释放持有的锁;wait是Object类的方法,用于线程间的通信,当线程执行wait时会释放它持有的锁,并进入等待池。

● 使用区域不同。sleep可以在任何地方使用,并且必须捕获可能出现的异常;wait必须放在同步控制方法和同步代码块中使用。

● 唤醒方式不同。sleep必须传递一个超时时间参数,超过指定时间后线程会自动唤醒;wait可以有两种形式,一种是无需传递参数,线程会进入无限期的等待状态,直到被其他线程的notify或notifyAll唤醒;另一种是传递参数,线程会在指定时间后醒来。

● 释放锁资源不同。sleep不会释放锁;wait会释放锁,使得其他线程可以访问被锁定的资源。

5、什么是线程安全

多个线程同时运行一段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。同一个实例对象在被多个线程使用的情况下也不会出现计算失误,也是线程安全的,反之则是线程不安全的。

7、线程的状态?

实线程一般具有五种状态,即创建、就绪、运行、阻塞、终止。

1.  在这里插入图片描述新建( new ):新创建了一个线程对象。

2.  可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象的start ()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取 cpu 的使用权 。

3.  运行( running ):可运行状态( runnable )的线程获得了 cpu 时间片( timeslice ),执行程序代码。

4.  阻塞( block ):阻塞状态是指线程因为某种原因放弃了 cpu 使用权,也即让出了 cpu timeslice ,暂时停止运行。直到线程进入可运行( runnable )状态,才有机会再次获得 cpu timeslice 转到运行( running )状态。阻塞的情况分三种:

● a.等待阻塞:运行( running )的线程执行 o.wait ()方法,JVM 会把该线程放 入等待队列( waitting queue )中。

● b.同步阻塞:运行( running )的线程在获取对象的同步锁时, 若该同步锁被别的线程占用,则 JVM 会把该线程放入锁池( lock pool )中。

● c.其他阻塞: 运行( running )的线程执行 Thread . sleep ( long ms )或 t.join ()方法,或者发出了 I / O 请求时,JVM 会把该线程置为阻塞状态。当 sleep ()状态超时、 join ()等待线程终止或者超时、或者 I / O 处理完毕时,线程重新转入可运行( runnable )状态。

1.  死亡( dead ):线程 run ()、 main () 方法执行结束,或者因异常退出了 run ()方法,则该线程结束生命周期。死亡的线程不可再次复生。

8、线程间通信的几种实现方式?

1.  使用 volatile 关键字。基于 volatile 关键字来实现线程间相互通信是使用共享内存的思想,大致意思就是多个线程同时监听一个变量,当这个变量发生变化的时候 ,线程能够感知并执行相应的业务。这也是最简单的一种实现方式。

2.  使用Object类的wait() 和 notify() 方法。Object类提供了线程间通信的方法:wait()、notify()、notifyaAl(),它们是多线程通信的基础,而这种实现方式的思想自然是线程间通信。

注意: wait和 notify必须配合synchronized使用,wait方法释放锁,notify方法不释放锁

9线程属性

编号(ID):用于标识线程的唯一编号,只读属性。

名称 (Name):用于定义线程名称,可读可写。

线程类别(Daemon):通过线程的 setDaemon(boolean on) 方法进行设置,为 true 表示设置为守护线程,否则为用户线程。用户线程会阻止 Java 虚拟机正常停止,守护线程则不会。通常可以把一些不重要的线程设置为守护线程,比如监控其他线程状态的监控线程,当其他工作线程停止后,虚拟机就可以正常退出。

优先级 (Priority):Java 线程支持 1 到 10 十个优先级,默认值为 5 。Java 线程的优先级本质上只是给线程调度器一个提示信息,它并不能保证线程一定按照优先级的高低顺序运行,所以它是不可靠的,需要谨慎使用。在 Java 平台中,子线程的优先级默认与其父线程相同。

10Java 线程的生命周期分为以下五类状态:

RUNABLE:该状态包括两个子状态:READY 和 RUNING 。处于 READY 状态的线程被称为活跃线程,被线程调度器选中后才开始运行,转化为 RUNING 状态。

BLOCKED:一个线程发起一个阻塞式 IO 操作后(如文件读写或者阻塞式 Socket 读写),或者申请一个由其他线程持有的独占资源(比如锁)时,相应的线程就会处于该状态。

WAITING:线程处于无时间限制的等待状态。

TIMED_WAITING:有时间限制的等待状态,如果在指定时间内并没有执行的特定的操作,则该线程自动转换为 RUNABLE。

TERMINATED:Thread.run()正常返回或者由于抛出异常而提前终止,则对应的线程都会处于该终止状态。

11线程的三大特性

线程有原子性、可见性和有序性三大特性。

原子性

对于涉及共享变量的操作,若该操作从其执行线程以外的任意线程来看都是不可分割的,那么我们就说该操作具有原子性。它包含以下两层含义:

访问(读、写)某个共享变量的操作从其执行线程以外的其他任何线程来看,该操作要么已经执行结束要么尚未发生,即其他线程不会看到该操作的中间部分的结果。

可见性

如果一个线程对某个共享变量进行更新之后,后续访问该变量的其他线程可以读取到这个更新结果,那么我们就称该更新对其他线程可见,反之则是不可见,这种特性就是可见性。出现可见性问题,往往意味着线程读取到了旧数据,这会导致更新丢失,从而导致运行结果与预期结果存在差异。可见性问题与计算机的存储结构和 Java 的内存模型都有着密切的关系。

有序性

源代码顺序:程序员编写的代码的执行顺序;

程序顺序:编译后的代码的执行顺序;

执行顺序:给定代码在处理器上的实际执行顺;

感知顺序:处理器感知到的其他处理器上代码的执行顺序。

在 Java 语言中,volatile 和 synchronized 都能够保证有序性:

volatile:通过内存屏障来禁止指令重排序,通过加载屏障和存储屏障来冲刷写缓冲器和清空无效化队列,从而可以避免内存重排序的现象;

synchronized :使用 synchronized 修饰的变量在同一时刻只允许一个线程对其进行 lock 操作,这种限制决定了持有同一个锁的两个同步块只能串行执行,也就避免了乱序问题。

12ThreadLocal的理解

ThreadLocal 主要功能有两个:

● 第一个是可以实现资源对象的线程隔离,让每个线程各用各的资源对象,避免争用引发的线程安全问题

● 第二个是实现了线程内的资源共享

面试官:好的,那你知道ThreadLocal的底层原理实现吗?

在ThreadLocal内部维护了一个一个 ThreadLocalMap 类型的成员变量,用来存储资源对象

当我们调用 set 方法,就是以 ThreadLocal 自己作为 key,资源对象作为 value,放入当前线程的 ThreadLocalMap 集合中

当调用 get 方法,就是以 ThreadLocal 自己作为 key,到当前线程中查找关联的资源值

当调用 remove 方法,就是以 ThreadLocal 自己作为 key,移除当前线程关联的资源值

面试官:好的,那关于ThreadLocal会导致内存溢出这个事情,了解吗?

是应为ThreadLocalMap 中的 key 被设计为弱引用,它是被动的被GC调用释放key,不过关键的是只有key可以得到内存释放,而value不会,因为value是一个强引用。

在使用ThreadLocal 时都把它作为静态变量(即强引用),因此无法被动依靠 GC 回收,建议主动的remove 释放 key,这样就能避免内存溢出。

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

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

相关文章

Python 面试【★★★】

阐述以下方法 classmethod, staticmethod, property? 解释什么是lambda函数?它有什么好处?

手机远程控制另一台手机的全新使用教程(安卓版)

看完这篇文章,你可以了解到安卓手机如何远程控制安卓手机,以及苹果手机如何远程控制安卓手机。 如果想要用安卓手机远程管控苹果手机,或者苹果手机远程管控另一台苹果手机,请点击查看视频《手机远程管控另一台手机的全新使用教程…

springcloud第4季 分布式事务seata作用服务搭建1

一 seata作用 1.1 seata简介 1.seata是一款解决分布式事务的解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。 1.2 seata的术语 一个中心:全局事务id,xid,在调用服务链路的上下文中进行传播。TC(Transa…

使用API有效率地管理Dynadot域名,为文件夹中的域名设置域名转发

关于Dynadot Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮…

VUE大屏的开发过程(纯前端)

写在前面,博主是个在北京打拼的码农,工作多年做过各类项目,最近心血来潮在这儿写点东西,欢迎大家多多指教。 对于文章中出现的任何错误请大家批评指出,一定及时修改。有任何想要讨论和学习的问题可联系我:1…

基于Redis和openresty实现高并发缓存架构

目录 概述缓存架构设计实践代码路由业务封装redis 效果 概述 本文是对项目中 QPS 高并发相关问题的一种解决方案,利用 Nginx 与 Redis 的高并发、超低延迟响应,结合 Canal 进行实现。 openrestry官网 当程序需要提供较高的并发访问时,往往需…

基于大数据架构的内容安全风控与分析

1 项目介绍 1.1 研究目的和意义 在数字化时代,内容安全成为了互联网企业面临的一个重要挑战。海量数据的产生与传播,伴随着不良信息和网络安全威胁的日益增加。因此,本课题旨在通过构建一个基于大数据架构的内容安全风控与分析系统&#xf…

概率论论文(关于“到课率”的贝叶斯推理应用)

概率论论文(关于“到课率”的贝叶斯推理应用) 全条件概率公式和贝叶斯公式趣味识 思考1: (引自贝叶斯公式及朴素贝叶斯分类算法应用初探) “狼来了”的故事想必大家都知道,小孩子第三次对村民说狼来了的时候,村民们没有相信他的话&#xff0…

基于weixin小程序农场驿站系统的设计

管理员账户功能包括:系统首页,个人中心,农场资讯管理,用户管理,卖家管理,用户分享管理,分享类型管理,商品信息管理,商品类型管理 开发系统:Windows 架构模式&…

【新手友好】计算机SCI期刊,IF=3+,编辑负责,修改稿件认真

一、期刊名称 Journal of Communications and Networks 二、期刊简介概况 期刊类型:SCI 学科领域:计算机科学 影响因子:3.6 中科院分区:3区 三、期刊征稿范围 《通信与网络杂志》每年出版六期,致力于发表高质量的…

Spring-Boot整合Redis【随记】

基于spring boot整合. 1 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 2 编写redis的配置文件 application.yml进行编写. 属性: url por…

《昇思25天学习打卡营第3天 | 昇思MindSpore数据集 Dataset》

第三天 今天学习了不同的数据集加载方式、数据集常见操作和自定义数据集方法。 1.数据集加载。 以Mnist数据集为例。mindspore.dataset提供的接口仅支持解压后的数据文件&#xff0c;因此我们使用download库下载数据集并解压。 2.数据集迭代。 用create_tuple_iterator或create…

摒弃反模式:使用Kotlin委托优化Android BaseActivity

摒弃反模式&#xff1a;使用Kotlin委托优化Android BaseActivity 在Android开发中&#xff0c;许多开发者习惯于创建名为“BaseActivity”或“BaseFragment”的基类&#xff0c;以便在所有Activity或Fragment中共享一些通用行为。这种方法乍一看似乎是个好主意&#xff0c;但实…

Kotlin 中的内联函数

1 inline 内联函数&#xff1a;消除 Lambda 带来的运行时开销。 举例来说&#xff1a; fun main() {val num1 100val num2 80val result num1AndNum2(num1, num2) { n1, n2 ->n1 n2} }fun num1AndNum2(num1: Int, num2: Int, operation: (Int, Int) -> Int): Int …

Docker 安装最新版本 Jenkins

目录 1、下载、启动容器、更新到最新版本 2、查看初始密码两种方式&#xff1a; 3、默认安装的部分未汉化&#xff0c;删除默认的汉化插件。重启容器&#xff0c;重新安装汉化插件 4、安装 Publish over SSH、docker-build-step 、Docker Commons 插件 5、配置服务器连接信…

【红帽战报】6月RHCE考试喜报!

往期战报回顾&#xff1a; 点击查看【战报】5月RHCE考试喜报&#xff01;通过率100% 点击查看【战报】4月份红帽考试战报&#xff01; 点击查看【战报】PASS&#xff01;PASS&#xff01;2023年终来一波RHCE考试 微思网络-红帽官方授权合作伙伴&#xff01;面向全国招生&…

Python爬取中国天气网天气数据.

一、主题式网络爬虫设计方案 1.主题式网络爬虫名称 名称&#xff1a;Python爬取中国天气网天气数据 2.主题式网络爬虫爬取的内容与数据特征分析 本次爬虫主要爬取中国天气网天气数据 3.主题式网络爬虫设计方案概述&#xff08;包括实现思路与技术难点&#xff09; reques…

[火灾警报系统]yolov5_7.0-pyside6火焰烟雾识别源码

国内每年都会发生大大小小的火灾&#xff0c;造成生命、财产的损失。但是很多火灾如果能够早期发现&#xff0c;并及时提供灭火措施&#xff0c;将会大大较小损失。本套源码采用yolov5-7.0目标检测算法结合pyside6可视化界面源码&#xff0c;当检测到火灾时&#xff0c;能否发出…

第三阶段Spark

Spark和PySpark的介绍 PySpark的相关设置 安装PySpark库 pip install pyspark pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyspark 构建PySpark执行环境入口对象 # 导包 from pyspark import SparkConf, SparkContext# 创建SparkConf类对象 conf SparkConf()…

多行业预约门店服务小程序源码系统 支持多门店预约 带完整的安装代码包以及搭建教程

系统概述 该系统基于先进的云计算和大数据技术&#xff0c;采用模块化设计&#xff0c;具有高度的可扩展性和可定制性。无论是餐饮、美容美发、健身房还是其他服务行业&#xff0c;都可以通过该系统轻松实现多门店预约功能。同时&#xff0c;我们还提供了丰富的接口和插件&…