【面试专题】并发编程篇①

news2024/12/29 0:04:57

📃个人主页:个人主页

🔥系列专栏:Java面试专题

1.线程和进程的区别

线程和进程都是操作系统中的概念,它们的主要区别如下:

  1. 资源分配:进程是操作系统中的资源分配的基本单位,每个进程都有独立的内存空间、文件句柄等资源,而线程是进程中的一个实体,它与其他线程共享同一进程的资源。

  2. 调度:进程拥有自己的调度器,由操作系统负责进行调度,而线程则由进程的调度器进行调度,操作系统不能直接对线程进行调度。

  3. 运行效率:线程相比进程来说更加轻量级,创建和销毁的开销小,切换上下文也更快,因此线程的运行效率更高。

  4. 通信方式:进程之间的通信需要经过操作系统的管道或共享内存等机制,而线程之间可以直接共享同一进程的内存空间,因此线程间通信更加快捷。

2.并行与并发的区别

在多核CPU的情况下:

并发是同一时间应对多件事情的能力,例如:多个线程轮流使用一个CPU。

并行是同一时间动手做多件事情的能力,例如:4核CPU同时执行4个线程。

3.创建线程的方式有哪些

  1. 通过继承Thread类创建线程。需要重写run()方法,启动线程时,通过调用start()方法启动。
  2. 通过实现Runnable接口创建线程。需要重写run()方法,启动线程时,将自定义类的实例作为一个参数,调用Thread的构造方法,得到一个线程实例,再调用start()方法启动。
  3. 通过实现Callable接口创建线程。需要重写call()方法,启动线程时,需要新建一个Callable的实例,再用FutureTask实例包装它,最终再包装成Thread实例,调用start()方法启动,并且可以通过FutureTask的get()方法来获取返回值。
  4. 使用线程池,可以通过调用Executors类的静态方法创建线程池,然后向线程池中提交任务来创建线程。

4.Runnable和Callable有什么区别

  1. Runnable不会返回结果或抛出异常,而Callable会返回结果或抛出异常。

  2. Callable接口中定义的方法是call()方法,而Runnable接口中定义的方法是run()方法。

  3. Callable可以通过Future接口来获取执行结果,而Runnable没有这样的机制。

  4. Callable的call()方法可以抛出异常,而Runnable的run()方法不能抛出异常。

5.run()和start()有什么区别

  1. run()方法定义了线程的主要内容,是实际执行的代码。但是,当使用run()方法时,代码执行在当前线程中,并没有创建新线程。可以被调用多次(就和普通方法一样)

  2. start()方法启动一个新线程来执行run()方法中的代码。当使用start()方法时,代码将在新线程中执行,并且在主线程中继续执行其他代码。只能被调用一次。

6.线程包括那些状态

Java线程包括如下状态:

  1. 新建状态(New):当线程对象被创建时,它处于新建状态。

  2. 可执行状态(Runnable):当调用start()方法后,线程开始执行,进入可运行状态。可运行状态包括正在运行和就绪两种情况。

  3. 阻塞状态(Blocked):如果没有获取锁(synchronized或lock)进入阻塞状态,获得锁再切换为可执行状态

  4. 等待状态(Waiting):如果线程调用wait()方法进入等待状态,其他线程调用notify()唤醒后可以切换为可执行状态

  5. 计时等待状态(Timed Waiting):如果线程调用sleep(100)方法,进入计时等待状态,到时间后可切换为可执行状态

  6. 终止状态(Terminated):线程执行完成或者发生了未捕获的异常,进入终止状态。

7.新建T1、T2、T3三个线程,如何保证他们顺序执行

可以使用线程.join()方法来保证三个线程的顺序执行。具体实现方法如下:

public class Main {  
    public static void main(String[] args) {  
        Thread t1 = new Thread(new Runnable() {  
            @Override  
            public void run() {  
                // 线程T1的代码  
                System.out.println("Thread T1");  
            }  
        });  
        Thread t2 = new Thread(new Runnable() {  
            @Override  
            public void run() {  
                // 线程T2的代码  
                System.out.println("Thread T2");  
            }  
        });  
        Thread t3 = new Thread(new Runnable() {  
            @Override  
            public void run() {  
                // 线程T3的代码  
                System.out.println("Thread T3");  
            }  
        });  
        // 启动线程,并使用join()保证顺序执行  
        t1.start();  
        t1.join(); // 等待t1执行完毕  
        t2.start();  
        t2.join(); // 等待t2执行完毕  
        t3.start();  
        t3.join(); // 等待t3执行完毕  
    }  
}

8.notify()和notifyAll()有什么区别

notify()notifyAll()都是Java中用于线程同步的方法,但它们的使用方式和作用有所不同。

  1. notify():这个方法用于唤醒在此对象监视器上等待的单个线程。如果有多个线程在等待,它将唤醒其中一个线程。被唤醒的线程将获得锁,然后执行。
  2. notifyAll():这个方法用于唤醒在此对象监视器上等待的所有线程。当一个线程在对象上调用wait()方法时,它会在那个对象上等待,直到其他线程在该对象上调用notify()notifyAll()方法。当notifyAll()方法被调用时,所有在该对象上等待的线程都会被唤醒,所有的这些线程将尝试获取锁,然后其中的一个将获得锁并执行。

简单来说,notify()用于唤醒单个线程,而notifyAll()用于唤醒所有等待的线程。在多线程编程中,合理使用这两个方法可以帮助我们更好地控制线程的执行顺序和同步。

9.在java中wait和sleep方法的不同

在Java中,wait()sleep()方法都是用来暂停线程的执行,但是它们的使用方式和效果有很大的不同。

sleep()方法:这个方法是Thread类的一个静态方法。它会使当前线程暂停执行一段时间,这段时间内线程不会消耗CPU资源。在指定的时间间隔之后,线程会重新启动。注意,sleep()方法需要一个参数,这个参数是线程暂停的时间,单位是毫秒。

Thread.sleep(2000);  // 线程会暂停2秒

wait()方法:这个方法是Object类的一个成员方法。它会使当前线程等待,直到其他线程调用同一个对象的notify()notifyAll()方法。在等待期间,线程不会消耗CPU资源。注意,wait()方法需要在对象上调用,并且需要在一个同步上下文中。也就是说,它通常被包含在一个synchronized块或者方法中。

synchronized (object) {  
    while (<condition does not hold>)  
        object.wait();  
    // perform action appropriate to condition  
}

在这个例子中,线程会等待,直到<condition does not hold>变为false。然后,线程会继续执行。

总的来说,sleep()wait()的主要区别在于:

  • sleep()是静态方法,可以在任何地方调用,但它不会检查任何条件;而wait()是对象的方法,必须在同步上下文中调用,它会检查一个条件并决定是否等待。
  • sleep()会导致线程阻塞一段时间,这段时间内线程不会消耗CPU资源;而wait()会导致线程进入等待状态,直到其他线程调用同一个对象的notify()notifyAll()方法。在这段时间内,线程不会消耗CPU资源。
  • sleep()wait()都需要一个时间参数,但是这个参数的含义不同。对于sleep(),它是暂停的时间;对于wait(),它是等待的最大时间(毫秒),如果在这个时间内没有接收到通知,那么线程会重新竞争锁并重新检查条件。

10.如何停止一个正在运行的线程

①使用一个标志位来通知线程可以安全地终止其执行

class MyThread extends Thread {  
    private volatile boolean running = true;  
  
    public void run() {  
        while (running) {  
            // ... do some work ...  
        }  
    }  
  
    public void shutdown() {  
        running = false;  
    }  
}

在这个例子中,当shutdown()方法被调用时,线程将停止其执行。当然,线程应该定期检查running变量的值,并在可能的情况下安全地退出循环。这样,线程就可以在适当的时候结束其执行。

②使用stop方法强行终止(不推荐,方法已经作废)

③使用interrupt方法中断线程

在Java中,你可以使用interrupt方法来尝试中断一个线程。但是,你需要注意的是,interrupt方法并不会立即终止线程,而是会设置一个中断标记,你需要在线程的中断处理代码中响应这个中断。

以下是一个简单的例子,说明如何中断一个线程:

public class MyThread extends Thread {  
    public void run() {  
        while (!Thread.currentThread().isInterrupted()) {  
            // 线程的逻辑...  
        }  
    }  
}  
  
public class Main {  
    public static void main(String[] args) {  
        MyThread myThread = new MyThread();  
        myThread.start();  
  
        // 在需要的时候中断线程  
        myThread.interrupt();  
    }  
}

在这个例子中,MyThread类继承了Thread,并重写了run方法。在run方法中,我们在循环中检查线程是否被中断。如果线程被中断,isInterrupted方法会返回true,这样我们就可以退出循环。

在主方法中,我们创建了一个MyThread对象,并启动了线程。然后,我们使用interrupt方法来中断线程。

请注意,这只是一个简单的例子。在实际的程序中,你可能需要在更复杂的逻辑中处理线程的中断。例如,如果你的线程是在一个阻塞操作(如Thread.sleepObject.wait)中,那么当调用interrupt方法时,线程会收到一个InterruptedException。你需要在代码中处理这个异常,并响应中断。

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

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

相关文章

IDEA优雅自动生成类注释和快捷键生成方法注释

生成类注释 Preferences->Editor->File and Code Templates-> Includes ->File Header 注释模板&#xff1a; /*** Classname ${NAME}* Description ${description}* Date ${DATE} ${TIME}* Created by ZouLiPing*/生成方法和字段注释 查看IDEA自动配置java快捷…

Istio实战(十)-Envoy 请求解析(上)

前言 Envoy 是一款面向 Service Mesh 的高性能网络代理服务。它与应用程序并行运行,通过以平台无关的方式提供通用功能来抽象网络。当基础架构中的所有服务流量都通过 Envoy 网格时,通过一致的可观测性,很容易地查看问题区域,调整整体性能。 Envoy也是istio的核心组件之一…

使用cpufrequtils查看调整cpu频率及模式

使用cpufrequtils查看调整cpu频率及模式 cpufrequtils是一个查看和修改CPU频率GHz的工具 有些物理服务器使用默认频率进行运行&#xff0c;这时可以使用该工具进行就该CPU的核心频率 安装: apt install cpufrequtils yum install cpufrequtils 使用: # 查看全部核心详细信息…

1111111111111

一、集合 1.1 简介 集合主要分为两组&#xff08;单列集合、双列集合&#xff09;&#xff0c;Collection 接口有两个重要的子接口 List 和Set&#xff0c;它们的实现子类都是单列集合。Map 接口的实现子类是双列集合&#xff0c;存放的是 K-V 1.2 关系图 二、Collection 接口…

Shadow DOM API 的 ShadowRoot 接口支持挂载的 shadow DOM 元素仅有18个:

<article, aside, blockquote, body, div, footer, h1-h6, header, main, nav, p, section, span> 浏览器兼容性 Browser compatibility

配置OSPF的多区域

实验6&#xff1a;配置多区域OSPF 实验需求 实现OSPF多区域配置阐明OSPF的LSA的类型阐明OSPF引入外部路由的配置方法阐明向OSPF引入缺省路由的方法 实验拓扑 配置多区域OSPF如图1-16所示。 图1-16 配置多区域OSPF 实验步骤 [1] IP地址配置 R1的配置 <Huawei>system…

Apache Doris (四十九): Doris表结构变更-动态分区(1)

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录

动态规划14:一和零

动态规划14&#xff1a;一和零 题目 474. 一和零 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的长度&#xff0c;该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素&#xff0c;集合 x 是集合 y 的 子集 。 …

计算机网络 第五章传输层

文章目录 1 传输层的功能2 传输层两种协议&#xff1a;UDP和TCP3 端口和端口号4 UDP数据报特点和首部格式5 UDP校验6 TCP协议的特点7 TCP报文段首部格式 1 传输层的功能 2 传输层两种协议&#xff1a;UDP和TCP 3 端口和端口号 4 UDP数据报特点和首部格式 5 UDP校验 6 TCP协议的…

机器人的触发条件有什么区别,如何巧妙的使用

简介​ 维格机器人触发条件,分为3个,分别是: 有新表单提交时、有记录满足条件时、有新的记录创建时 。 看似3个,其实是能够满足我们非常多的使用场景。 本篇将先介绍3个条件的触发条件,然后再列举一些复杂的触发条件如何用现有的触发条件来满足 注意: 维格机器人所有的…

ChatGLM系列四:P-Tuning微调

P-Tuning&#xff0c;参考ChatGLM官方代码 &#xff0c;是一种针对于大模型的soft-prompt方法 P-Tuning: 在输入的embedding层前&#xff0c;将prompt转换为可学习的额外一层embedding层. P-Tuning&#xff0c;仅对大模型的Embedding加入新的参数。 P-Tuning-V2&#xff0c;将…

FANUC机器人PRIO-621和PRIO-622设备和控制器没有运行故障处理

FANUC机器人PRIO-621和PRIO-622设备和控制器没有运行故障处理 如下图所示&#xff0c;新的机器人开机后提示报警&#xff1a; PRIO-621 设备没有运行 PRIO-622 控制器没有运行 我们首先查看下手册上的报警代码说明&#xff0c;如下图所示&#xff0c; 如下图所示&#xff0c…

蓝牙 - BLE SPP实现举例 (Bluecode Protocol Stack)

这里以一个无线扫描枪设备为例&#xff0c;这个设备会通过蓝牙通讯协议连接一个底座&#xff0c;使用的是BLE SPP进行通讯。 扫描枪用来扫条码&#xff0c;解析出条码信息后&#xff0c;将数据通过无线传输给底座&#xff0c;底座再通过USB将数据传送给电脑。 底座是Central d…

非科班出身的野生Android也可以跳到大厂

野生Android从业者&#xff0c;非科班出身&#xff0c;在小公司打杂2年后&#xff0c;"意外"地拿到了大厂的offer。 高中毕业后&#xff0c;我选择了一条不太寻常的路&#xff0c;&#xff08;花大几万&#xff09;进入编程培训班&#xff0c;后来又自修课程&#xf…

【LeetCode刷题-哈希】--387.字符串中的第一个唯一字符

387.字符串中的第一个唯一字符 class Solution {public int firstUniqChar(String s) {Map<Character,Integer> map new HashMap<>();for(int i 0;i<s.length();i){char c s.charAt(i);map.put(c,map.getOrDefault(c,0)1); }for(int i 0;i< s.length();i…

Java进阶(ConcurrentHashMap)——面试时ConcurrentHashMap常见问题解读 结合源码分析 多线程CAS比较并交换 初识

前言 List、Set、HashMap作为Java中常用的集合&#xff0c;需要深入认识其原理和特性。 本篇博客介绍常见的关于Java中线程安全的ConcurrentHashMap集合的面试问题&#xff0c;结合源码分析题目背后的知识点。 关于List的博客文章如下&#xff1a; Java进阶&#xff08;Lis…

IDEA MyBatisX插件介绍

一、前言 前几年写代码的时候&#xff0c;要一键生成DAO、XML、Entity基础代码会采用第三方工具&#xff0c;比如mybatis-generator-gui等&#xff0c;现在IDEA或Eclipse都有对应的插件&#xff0c;像IDEA中MyBatisX就是一个比较好用的插件。 二、MyBatisX安装配置使用 MyBa…

C的缺陷和陷阱读书笔记

词法陷阱 1、if语句的特殊用法 1、if(x>max) maxx;2、if(x>max?x;max) //条件表达式&#xff0c;是执行第二个&#xff0c;否执行第三个3、if(x>max); //条件成立后执行——空语句4、if((fopen(arg v[i],0))>0) //open函数执行&#xff0c;成功返回后面的0&a…

Maven系列第9篇:多环境构建,作为核心开发,这个玩不转有点说不过去!

如果你作为公司核心开发&#xff0c;打算使用maven来搭建项目骨架&#xff0c;这篇文章的内容是你必须要掌握的。 平时我们在开发系统的时候&#xff0c;会有开发环境、测试环境、线上环境&#xff0c;每个环境中配置文件可能都是不一样的&#xff0c;比如&#xff1a;数据库的…

Matlab2022b图文安装保姆级教程

注意&#xff1a;完成安装步骤1和步骤2之后&#xff0c;再去使用Matlab2022b 本次安装后的版本信息如下&#xff0c;64位软件&#xff0c;windows系统 Matlab2022a与2022b的比较 MATLAB主要用于数据分析、无线通信、深度学习、图像处理与计算机视觉、信号处理、量化金融与风险…