Java面试总结(六)

news2024/11/24 20:23:38

进程和线程的区别

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

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

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

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

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

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

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

创建线程的三种方式

使用继承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

创建三种线程的方式对比

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

  • 优势:
    Java的设计是单继承的设计,如果使用继承Thread的方式实现多线程,则不能继承其他的类,而如果使用实现Runnable接口或Callable接口的方式实现多线程,还可以继承其他类。
    采用接口能够更好的实现数据共享。线程的启动需要Thread类的start方法,如果采用继承的方式每次新建一个线程时,每个新建线程的数据都会单独的存在线程内存中,这样每个线程会单独的操作自己线程的数据,不能更好的实现线程之间的数据共享。

  • 劣势:
    编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

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

  • 优势:
    编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。

  • 劣势:
    线程类已经继承了Thread类,所以不能再继承其他的类。

Runnable和Callable的区别

与Runnable相比,Callable功能更强大些

  • Callable规定(重写)的方法是call(),Runnable规定(重写)的方法是run()。
  • Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
  • call方法可以抛出异常,run方法不可以。
  • Callable是支持泛型的
  • 运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

Runnable接口源码

@FunctionalInterface
public interface Runnable {

    public abstract void run();
}

Callable接口源码

@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result //可以有返回值
     * @throws Exception if unable to compute a result  //可以抛出异常
     */
    V call() throws Exception;
}

Callable接口使用案例

/*
创建线程的方式三:实现Callable接口。-----JDK1.5新增
 */
//1.创建一个实现Callable的实现类
class NumThread implements Callable{
    //2.实现call方法,将此线程需要执行的操作声明在call()中
    @Override
    public  Object call() throws Exception{
        int sum=0;
        for (int i=1;i<=100;i++){
            sum+=i;
        }
        return sum;
    }
}
public class ThreadNew {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //3.创建Callable接口实现类的对象
        NumThread numThread=new NumThread();
        //4.将此Callable接口实现类的对象作为传递到FutureTask构造中,创建FutureTask的对象
        FutureTask futureTask=new FutureTask(numThread);
        //5.将FutureTask的对象组排位哦参数传递到thread类的构造器中,创建Thread对象,并调用start()
        new Thread(futureTask).start();
      
        //6.获取Callable中call方法的返回值
        //get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值
        Object sum = futureTask.get();
        System.out.println("总和为:"+sum);
    }
}

线程的状态

  1. NEW:初始状态,线程刚刚被创建出来,还没有调用 start() 方法;
  2. RUNABLE:运行中状态,调用了 start() 方法,Java 线程将操作系统中的 就绪/可运行(READY)状态和 运行(RUNNING)状态统称为 RUNABLE 状态;
  3. BLOCK:阻塞状态,线程阻塞于锁,需要等待锁的释放;
  4. WAITING:等待状态,进入等待状态表示需要等待其他线程做出一些特定的状态(通知或中断);
  5. TIMED_WAITING:超时等待状态,可以在指定时间后自行返回,而不是像WAITING状态一样一直等待;
  6. TEMENATED:终止状态,表示当前线程已经执行完毕。

在这里插入图片描述

  • 由上图可以看出:线程创建之后它将处于 NEW(初始) 状态,调用 start() 方法后开始运行,线程这时候处于 READY(就绪/可运行) 状态。可运行状态的线程获得了 CPU 时间片(timeslice)后就处于 RUNNING(运行) 状态。

  • 在操作系统层面,线程有 READY 和 RUNNING 状态;而在 JVM 层面,只能看到 RUNNABLE 状态,所以 Java 系统一般将这两个状态统称为 RUNNABLE(运行中) 状态 。

  • 为什么 JVM 没有区分这两种状态呢?
    java 现在的时分(time-sharing)多任务(multi-task)操作系统架构通常都是用所谓的“时间分片(time quantum or time slice)”方式进行抢占式(preemptive)轮转调度(round-robin 式)。这个时间分片通常是很小的,一个线程一次最多只能在 CPU 上运行比如 10-20ms 的时间(此时处于 running 状态),也即大概只有 0.01 秒这一量级,时间片用后就要被切换下来放入调度队列的末尾等待再次调度。(也即回到 ready 状态)。线程切换的如此之快,区分这两种状态就没什么意义了。

  • 当线程执行 wait()方法之后,线程进入 WAITING(等待) 状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态。

  • TIMED_WAITING(超时等待) 状态相当于在等待状态的基础上增加了超时限制,比如通过 sleep(long millis)方法或 wait(long millis)方法可以将线程置于 TIMED_WAITING 状态。当超时时间结束后,线程将会返回到 RUNNABLE 状态。

  • 当线程进入 synchronized 方法/块或者调用 wait 后,(被 notify)想要重新进入 synchronized 方法/块时,但是锁被其它线程占有,这个时候线程就会进入 BLOCKED(阻塞) 状态。

  • 线程在执行完了 run()方法之后将会进入到 TERMINATED(终止) 状态。

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

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

相关文章

狂扫近300万读者,蟒蛇书升级版即将出版,招募审读人

狂扫全世界近 300 万爱好者成为编程领域的现象级爆品豆瓣累计超过 5000 人评价第2版中文版获得了 9.3 分的好评Amazon 近 10000 人评价第2版原版获得了 4.7 星好评毫不夸张&#xff0c;它是全世界读者心中的 Python 入门圣经因为封面上是一只蠢萌的蟒蛇这本书又被读者亲切地称为…

SQL注入——文件上传

目录 一&#xff0c;mysql文件上传要点 二&#xff0c;文件上传指令 一句话木马 三&#xff0c;实例 1&#xff0c;判断注入方式 2&#xff0c;测试目标网站的闭合方式&#xff1a; 3&#xff0c;写入一句话木马 4&#xff0c;拿到控制权 一&#xff0c;mysql文件上传…

【面试系列】volatile的底层原理

并发编程的三大特性 原子性可见性原子性 JAVA内存模型 Java内存模型&#xff08;Java Memory Model&#xff09;主要分为主内存和线程工作内存。 主内存&#xff1a;方法区和堆空间 线程工作内存&#xff1a;虚拟机栈&#xff0c;本地方法栈&#xff0c;程序计数器。 所有…

centos安装docker详细步骤

目录 一.前言 1.环境要求2.官网中文安装参考手册 二.安装步骤 1.卸载旧版本2.安装需要的软件包3.设置docker镜像源 1.配置docker镜像源 方式1&#xff1a;官网地址(外国)&#xff1a;方式2&#xff1a;阿里云源&#xff1a;2.查看配置是否成功 4.更新yum软件包索引5.可以查看…

C++ | 探究函数重载的原理:函数名修饰【基于Windows + Linux双系统】

文章目录一、前言【中国乒乓和中国男足】【文言文一词多义】二、函数重载概念引入1、参数【类型】不同构成重载2、参数【个数】不同构成重载3、参数【类型顺序】不同构成重载三、函数重载的原理1、回顾程序编译 链接的过程2、Linux下【objdump】查看反汇编3、Windows下反汇编查…

Maven安装与配置,IDEA配置Maven

文章目录1. 安装本地Maven2. 安装3. 配置环境变量4. 配置settings.xml文件5. IDEA配置1. 安装本地Maven 官网下载&#xff1a;https://maven.apache.org/download.cgi 2. 安装 把下载好的maven压缩包解压到一个没有中文&#xff0c;空格或其他特殊字符的文件夹&#xff0c;…

数据结构与算法基础(王卓)(15):KMP算法详解(含速成套路和详细思路剖析)

如果时间不够&#xff0c;急&#xff08;忙&#xff09;着应付考试没心思看&#xff0c;直接参考&#xff08;照抄&#xff09;如下套路&#xff1a; PART 1&#xff1a;关于next [ j ] PPT&#xff1a;P30 根据书上以及视频上给出的思路&#xff08;提醒&#xff09;&#x…

JSONP劫持

注意&#xff1a;仅用于技术讨论&#xff0c;切勿用于其他用途&#xff0c;一切后果与本人无关&#xff01;&#xff01;&#xff01; 个人博客地址&#xff1a;HJW个人博客 扩展&#xff1a; 面试问题&#xff1a;CSRF的两种方法中&#xff0c;CORS和JSONP的区别&#xff1…

dubbo进阶——服务导出

服务导出 在这里记录一下对" Dubbo 导出服务的过程"的研究。 触发时机 public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener<ContextRefreshedEv…

代码随想录--数组--螺旋矩阵题型

n等于几&#xff0c;螺旋矩阵最外层行列数就等于几。如n等于3所以最外层一圈的行、列都是3个数字&#xff0c;如左图&#xff0c;n等于4所以最外层的行、列都是4个数字&#xff0c;如右图&#xff1a; 题目要求我们输出(以n3为例)[[123][894][765]]&#xff0c;题目只是给我们一…

MySQL:索引与事物

目录 简单了解索引的底层数据结构 索引的概念&#xff1a; 索引存在的意义&#xff1a; 索引的使用&#xff1a; 索引实现的数据结构 B树 B 树 B 树的特点 B 树的优势 事物 事物的概念 事物的使用 事物的四大特性 并发可能引起的问题 脏读问题 不可重复读 幻读…

未系安全带识别系统 yolo

未系安全带识别系统通过pythonyolo智能视频分析技术&#xff0c;未系安全带识别算法对画面中高空作业人员未系安全带行为进行监测&#xff0c;未系安全带识别算法监测到人员未穿戴安全带时&#xff0c;立即通知后台人员及时处理触发告警。Yolo算法采用一个单独的CNN模型实现end…

算法24:LeetCode_并查集相关算法

目录 题目一&#xff1a;力扣547题&#xff0c;求省份数量 题目二&#xff1a;岛屿数量 题目三&#xff1a;岛屿数量拓展 什么是并查集&#xff0c;举个简单的例子。学生考试通常会以60分为及格分数&#xff0c;我们将60分及以上的人归类为及格学生&#xff0c;而60分以下归…

mysql学习之数据系统概述

☀️马上要成为打工人&#xff0c;这几天把前面的知识都捡了捡&#xff0c;发现自己对关系数据库这块的学习还有所缺失&#xff0c;于是本章开始学习mysql 这里写目录标题1. 数据库系统的发展1.1 人工管理阶段1.2 文件系统阶段1.3 数据库阶段1.4 大数据阶段2 数据库系统的组成2…

扬帆优配|2600亿汽车巨头闪崩近9%,汽车股惊现“冰火两重天”!

今日早盘&#xff0c;A股全体低开震荡调整&#xff0c;首要股指跌逾1%&#xff0c;科创板体现略强&#xff0c;盘中一度直线拉升翻红&#xff0c;两市一度近4200股下跌。 盘面上&#xff0c;轿车服务、信创、半导体等板块相对强势&#xff0c;轿车整车、超导概念、一体压铸、建…

【MySQL】MySQL的索引

目录 介绍 索引的分类 索引的操作-创建索引-单列索引-普通索引 格式 操作 索引的操作-创建索引-单列索引-唯一索引 索引的操作-创建索引-单列索引-主键索引 索引的操作-创建索引-组合索引 索引的操作-全文索引 索引的操作-空间索引 索引的验证 索引的特点 介绍…

Lazada、Allegro、速卖通测评自养号技术(方法解析)

无论是亚马逊、拼多多Temu、shopee、Lazada、wish、速卖通、煤炉、敦煌、雅虎、eBay、TikTok、Newegg、乐天、美客多、阿里国际、沃尔玛、OZON、Joom、Facebook、Coupang、独立站、Cdiscount、Kaufland、DARTY、Allegro、MANO等平台测评自养号对于卖家来说算是一种低成本、高回…

什么?你不知道 ConcurrentHashMap 的 kv 不能为 null?

一、背景 最近设计某个类库时使用了 ConcurrentHashMap 最后遇到了 value 为 null 时报了空指针异常的坑。 本文想探讨下以下几个问题&#xff1a; &#xff08;1&#xff09; Map接口的常见子类的 kv 对 null 的支持情况。 &#xff08;2&#xff09;为什么 ConcurrentHashM…

Ethercat学习-电机调试问题总结

文章目录问题1&#xff1a;初始化不进入OP状态问题2&#xff1a;PDO通讯数据不对主站硬件&#xff1a;STM32F405LAN8720A主站软件&#xff1a;SOEM 问题1&#xff1a;初始化不进入OP状态 现象描述&#xff1a;主站初始化过程中&#xff0c;打印信息显示状态一直在safe-op&…

多态且原理

多态 文章目录多态多态的定义和条件协变&#xff08;父类和子类的返回值类型不同&#xff09;函数隐藏和虚函数重写的比较析构函数的重写关键字final和override抽象类多态的原理单继承和多继承的虚函数表单继承下的虚函数表多继承下的虚函数表多态的定义和条件 定义&#xff1…