Java多线程基础面试总结(一)

news2024/11/14 11:02:26

进程、线程和协程

进程、线程和协程

进程

进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建、运行到消亡的过程。

在Java中,当我们启动main函数其实就是启动了一个JVM进程,而main函数所在的线程其实就是这个进程中的一个线程,也称主线程。

在 Windows 中通过查看任务管理器的方式,我们就可以清楚看到 Windows 当前运行的进程(.exe 文件的运行)。

在这里插入图片描述

线程

线程与进程相似,但线程是一个比进程更小的执行单位,一个进程在其执行过程中可以产生多个线程。

各进程之间基本上是相互独立的,与进程不同的是同类线程共享进程的方法区资源,但每个线程都有自己的程序计数器Java虚拟机栈本地方法栈

系统产生一个线程或是在多个线程之间切换工作时,负担要比进程小得多,因此线程也被称作轻量级进程。

Java 程序天生就是多线程程序,一个 Java 程序的运行是 main 线程和多个其他线程同时运行。

进程和线程的区别

根本区别: 进程时操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。

资源开销: 每个进程都有自己独立的代码和数据空间(程序上下文),进程之间的切换开销比较大;线程可以看作轻量级进程,同类的线程共享进程的堆和方法区(JDK1.7及之前实现为永久代,JDK1.8及之后实现为元空间)资源,但是每个线程都有自己的程序计数器、Java虚拟机栈和本地方法栈,线程之间的切换开销比较小。

包含关系: 如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。

内存分配: 同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的。

影响关系: 一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉,所以多进程要比多线程健壮。

执行过程: 每个独立的进程有程序运行的入口、顺序执行序列和程序出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,两者均可并发执行。

总结: 线程是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。线程执行开销小,但不利于资源的管理和保护;而进程正相反。

协程

协程是一种轻量级的线程,协程的实现方式是在一个线程中,通过切换执行上下文来实现多个任务的并发执行。协程的切换不需要操作系统的介入,因此协程的切换速度非常快,开销也非常小。协程的特点是可以在一个线程中开启多个协程,每个协程之间共享线程的内存空间,因此协程也可以完成复杂的任务,如异步编程、爬虫、游戏等

线程与协程的区别

线程和协程都是多任务处理的技术,但是它们之间有很多区别,下面列举几点:

  1. 调度方式
    线程是由操作系统负责调度的,它们是操作系统的一种资源。线程的调度和切换需要操作系统的介入,开销比较大,但是线程的并发性和并行性比较高。
    **协程是由程序控制的,它们是用户空间的资源,不依赖于操作系统。**协程的切换和调度由程序控制,因此开销比较小,但是并发性和并行性比较低。

  2. 内存占用
    每个线程都需要独立的堆栈和寄存器等资源,协程则共享线程的这些资源,内存占用比较小。

  3. 编程复杂度
    线程需要考虑锁、同步、异步等问题,编程复杂度比较高。
    协程可以通过 yield、await 等关键字来实现状态的保存和恢复,编程复杂度比较低。

  4. 执行效率
    线程切换和调度需要操作系统的介入,开销比较大,执行效率比较低。
    协程切换和调度由程序控制,开销比较小,执行效率比较高。

总的来说,线程适用于 CPU 密集型的任务,协程适用于 I/O 密集型的任务。

线程适用于 CPU 密集型的任务,协程适用于 I/O 密集型的任务

线程和协程的适用场景主要是由于它们在任务调度方面的特点决定的。

对于 CPU 密集型的任务,比如大量的计算、排序等,需要大量的 CPU 资源,线程可以让程序在多个 CPU 核心上并行执行,从而提高执行效率。但是线程的切换和调度需要操作系统的介入,开销比较大,因此线程数量过多时,会降低程序的效率。

对于 I/O 密集型的任务,比如网络请求、文件读写等,需要等待 I/O 操作完成后才能继续执行后续任务,这时线程的执行效率就会受到限制。而协程可以通过 yield、await 等关键字来实现状态的保存和恢复,从而避免了线程切换的开销,提高了程序的效率,因此协程适用于 I/O 密集型的任务。

总之,线程适用于需要大量的 CPU 资源的任务,而协程适用于需要大量的 I/O 操作的任务。在实际应用中,我们需要根据具体的场景选择合适的技术来实现任务的处理。

创建线程的三种方式

使用继承Thread类的方式创建多线程

Thread类是Java提供的线程顶级类,继承Thread类可快速定义线程。

  • 使用多线程实现龟兔赛跑
public class TortoiseThread extends Thread{

    @Override
    public void run() {
        while (true) {
            System.out.println("乌龟领先了,加油.....," +
                    "当前线程的名称:" + this.getName() +
                    ",当前线程的优先级别:" + this.getPriority());
        }
    }

    public static void main(String[] args) {


        TortoiseThread tortoiseThread = new TortoiseThread();
        tortoiseThread.setName("乌龟线程");
        tortoiseThread.start();

        Thread.currentThread().setName("兔子线程");
        while(true){
            System.out.println("兔子领先了,add oil....,当前线程名称:"
                    +Thread.currentThread().getName()+",当前线程的优先级别:"
                    +Thread.currentThread().getPriority());
        }
    }
}
  • 运行结果截取(这里只截取了部分结果,应该是无限循环的)
乌龟领先了,加油.....,当前线程的名称:乌龟线程,当前线程的优先级别:5
乌龟领先了,加油.....,当前线程的名称:乌龟线程,当前线程的优先级别:5
兔子领先了,add oil....,当前线程名称:兔子线程,当前线程的优先级别:5
兔子领先了,add oil....,当前线程名称:兔子线程,当前线程的优先级别:5

使用实现Runnable接口的方式创建多线程

  • 使用多线程实现龟兔赛跑
public class TortoiseRunnable implements Runnable{
    @Override
    public void run() {
        while (true) {
            System.out.println("乌龟领先了,加油.....," +
                    "当前线程的名称:" + Thread.currentThread().getName() +
                    ",当前线程的优先级别:" + Thread.currentThread().getPriority());
        }
    }

    public static void main(String[] args) {

        Thread thread = new Thread(new TortoiseRunnable());
        thread.setName("乌龟线程");
        thread.start();

        Thread.currentThread().setName("兔子线程");
        while(true){
            System.out.println("兔子领先了,add oil....,当前线程名称:"
                    +Thread.currentThread().getName()+",当前线程的优先级别:"
                    +Thread.currentThread().getPriority());
        }
    }
}

  • 运行结果截取(这里只截取了部分结果,应该是无限循环的)
乌龟领先了,加油.....,当前线程的名称:乌龟线程,当前线程的优先级别:5
乌龟领先了,加油.....,当前线程的名称:乌龟线程,当前线程的优先级别:5
兔子领先了,add oil....,当前线程名称:兔子线程,当前线程的优先级别:5
兔子领先了,add oil....,当前线程名称:兔子线程,当前线程的优先级别:5

使用实现Callable接口的方式创建多线程

  • 使用多线程实现龟兔赛跑
public class TortoiseCallable implements Callable {
    @Override
    public Object call() throws Exception {
        while (true) {
            System.out.println("乌龟领先了,加油.....," +
                    "当前线程的名称:" + Thread.currentThread().getName() +
                    ",当前线程的优先级别:" + Thread.currentThread().getPriority());
        }
    }

    public static void main(String[] args) {

        TortoiseCallable tortoiseCallable = new TortoiseCallable();

        FutureTask futureTask = new FutureTask(tortoiseCallable);

        Thread thread = new Thread(futureTask);
        thread.setName("乌龟线程");
        thread.start();

        Thread.currentThread().setName("兔子线程");
        while(true){
            System.out.println("兔子领先了,add oil....,当前线程名称:"
                    +Thread.currentThread().getName()+",当前线程的优先级别:"
                    +Thread.currentThread().getPriority());
        }

    }
}

  • 运行结果截取(这里只截取了部分结果,应该是无限循环的)
乌龟领先了,加油.....,当前线程的名称:乌龟线程,当前线程的优先级别:5
乌龟领先了,加油.....,当前线程的名称:乌龟线程,当前线程的优先级别:5
兔子领先了,add oil....,当前线程名称:兔子线程,当前线程的优先级别:5
兔子领先了,add oil....,当前线程名称:兔子线程,当前线程的优先级别:5

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

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

相关文章

【Linux】全新服务器Centos7环境搭建和安装

1、简介 最近服务器重装后,环境啥的则需要从头全部搞一遍,于是开始搞起环境的配置和安装 2、环境配置安装 前期准备 给目录文件加文件传输权限(发现无法上传文件,于是增加权限 $ chmod 766 /home/lj/ 配置DNS服务 #配置DNS服务,如果没有8.8.8.8需要添加 cat /etc/re…

WRF模式与Python融合技术在多领域中的应用及精美绘图教程

当今从事气象及其周边相关领域的人员,常会涉及气象数值模式及其数据处理,无论是作为业务预报的手段、还是作为科研工具,掌握气象数值模式与高效前后处理语言是一件非常重要的技能。WRF作为中尺度气象数值模式的佼佼者,模式功能齐全…

QML控件--Dialog

文章目录一、控件基本信息二、控件使用三、属性成员四、成员函数五、信号一、控件基本信息 Import Statement:import QtQuick.Controls 2.14 Since:Qt 5.8 Inherits:Popup 二、控件使用 Dialog: 是一个弹出窗口,继承…

项目打包发布流程

---》》》项目打包发布 1.编译并构建项目 2.部署 npm i npm run build scp2:需要写代码 ---》》》 后续有空更新:赋几个链接: Jenkins官网 nullhttps://www.jenkins.io/zh/一文详解Jenkins的安装与配置Jenkins是一个基于Java开发的开源…

【SpringMVC】10—其他概念

⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记链接👉https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以,麻烦各位看官顺手点个star~😊 如果文章对你有所帮助,可以点赞👍…

2023年Web3的五大趋势

Web3 这个词有时被称为 "去中心化的互联网",涵盖了一些重要的互联网发展趋势。Web3 的愿景是创造一个不受大公司控制的互联网,如Alibaba、baidu、Google和Facebook,这些公司制定了互联网的大部分规则,掌控着我们今天可以…

HyperWorks2021软件安装教程

下载软件 https://www.xsoftnet.com/share/a0004MWyQAg9r.html产品介绍: HyperWorks一款功能强大的开放式架构仿真软件。拥有先进的技术以及高性能、高效和创新的产品,为用户提供了设计、仿真和制造等服务。支持电磁分析设计、材料建模制造、多物理场分…

学校的地下网站(学校的地下网站1080P高清)

这个问题本身就提得有问题,为什么这么说,这是因为YouTube本身就不是一个视频网站或者说YouTube不是一个传统的视频网站!!! YouTube能够一家独大,可不仅仅是因为有了Google 这个亲爹,还有一点&am…

Flutter Web 开发实践与优化

一,Flutter Web架构 目前,除了可以支持Android、iOS移动跨平台开发之外,Flutter还支持macOS、Windows、Linux和Web等多个跨平台的开发。可以说,作为一款先进的跨平台开发框架,Flutter已经真正意义上实现了“一次编写,处处运行”的美好愿景。 众所周知,Dart 语言存在之…

【建议收藏】数据库 SQL 入门——事务(内附演示)

文章目录📚引言📖事务📑事务的概念📑事务操作🔖查看与设置事务提交方式🔖提交事务与回滚事务📑事务的特性📑并发事务问题📑事务隔离级别📍总结📚引…

8.基于拉丁超立方法的风光场景生成与削减

matlab代码:基于拉丁超立方法的风光场景生成与削减 摘要:与蒙特卡洛法不同,拉丁超立方采样改进了采样策略能够做到较小采样规模中获得较高的采样精度,属于分层抽样技术,设定风光出力遵从正态分布normrnd,从…

字节面试体验值拉满~

今天分享一位读者春招的字节二面面经,岗位是后端开发。 一个编程语言都没问,都是问网络项目mysqlredis。 问题记录 使用消息中间件降低消息持久化的压力是怎么做的,为什么可以降低? 读者答:在突发大量消息的情况下…

水塘抽样解决随机选择问题

1.简介 水塘抽样是一系列的随机算法,其目的在于从包含n个项目的集合S中选取k个样本,其中n为一很大或未知的数量,尤其适用于不能把所有n个项目都存放到内存的情况。最常见例子为Jeffrey Vitter在其论文中所提及的算法R。 2.算法步骤&#xff1…

AD823AARZ-RL-ASEMI代理亚德诺AD823AARZ-RL车规级芯片

编辑-Z AD823AARZ-RL芯片参数: 型号:AD823AARZ-RL −3dB带宽:17 MHz 全功率响应:4.8 MHz 斜率:30 V/s 输入电压噪声:14 nV/√Hz 输入电流噪声:1 fA/√Hz 初始偏移量:0.12mV …

nacos集群配置高可用数据库

1.架构 nacos集群配置高可用数据库的架构其实和nacos集群的架构差不多,只是在数据库方面做了主从跟keepalive实现数据库的高可用,当mysql的master节点挂掉时,keepalive的vip自动漂移到slave节点,并通过脚本使slave节点提升为mast…

Leetcode.1992 找到所有的农场组

题目链接 Leetcode.1992 找到所有的农场组 Rating : 1539 题目描述 给你一个下标从 0 开始,大小为 m x n 的二进制矩阵 land ,其中 0 表示一单位的森林土地,1 表示一单位的农场土地。 为了让农场保持有序,农场土地之…

QT程序退出还占进程

问题情况 程序运行时的样子: 程序退出时的样子: 其跑到了后台进程里面: 程序退出了,但在任务管理器里查看,其从进程里面转移到后台进程了。 这种问题,怎么办,代码里,应该释放的也都…

微信小程序引入广告位功能,详细步骤!!!

大家碰到过首页加载时一开始出现的广告页面,这种微信官方提供了一个api进行设置,下面我们来详细解释一下。 首先第一步需要小程序累计用户数达到1000即可开通流量主,成功开通流量主之后就可以创建相应的广告位了,包括banner广告、…

【设计模式】如何在业务开发中使用适配器模式?

文章目录前言适配器模式定义通用代码实现适用场景案例场景分析一坨坨代码实现适配器模式重构总结前言 适配器模式(Adapter Pattern):将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个…

Can‘‘t connect to MySQL server on localhost (10061)解决方法

首先检查MySQL 服务没有启动》如果没有启动,则要启动这个服务。 有时候安装mysql后使用mysql命令时报错 Cant connect to MySQL server on localhost (10061),或者用net start mysql 时报服务名无效,一般是因为mysql服务没有启动。 打开 powe…