首页 > 编程语言 >java八股——java并发(1)

java八股——java并发(1)

时间:2024-03-18 22:58:44浏览次数:29  
标签:状态 八股 调用 java Thread 并发 线程 执行 方法

上一篇传送门:点我

java面试中,并发相关的一些面试题整理,很多部分仅为个人理解,如有问题欢迎讨论指正(待补充)。

并行与并发有什么区别?

并行和并发都是指多个任务同时执行的概念,但是 它们之间有着明显的区别。
并行是指多个任务在同一时刻同时运行,通常会需要使用多个处理器或者多核处理器来实现;而并发指的是多个任务的执行是交替进行的,一个任务执行一段时间后,再去执行另一个任务,它是通过操作系统的协作调度来实现各个任务的切换,从而达到看上去同时进行的效果。
举个例子,假设现在有一个四核的CPU,并行处理就可以让这四个处理器核心同时处理四个不同的任务,每个处理器核心都在独立地工作。而并发处理则是让这四个任务在一个处理器核心上轮流执行,每个任务得到一点时间片来运行,然后就被切换到下一个任务,此时同一时刻只有一个任务在执行。

说说什么是进程与线程 / 说说进程与线程之间的区别

进程和线程是操作系统中概念,用于描述程序运行时的执行实体。
进程是一个程序在执行过程中的一个实例可以并发地执行多个任务,每个进程都有自己独立的地址空间,也就是说它们不能直接共享内存,两个进程之间需要通过进程间通信(IPC)来交换数据
线程进程中的一个执行单元,一个进程里可以包含多个线程,同一个进程中的多个线程可以并发地执行多个任务,并且这些线程共享进程的内存空间
线程相比于进程,线程的创建和销毁开销较小,上下文切换开销也较小,因此线程是实现多任务并发的一种更轻量级的方式。

Java线程的创建方式主要有哪几种?

Java中创建线程主要有三种方式。它们分别是继承Thread类、实现Runnable接口、实现Callable接口,但它们的底层实际上都是基于Runnable接口。

继承Thread类:

public class MyThread extends Thread{
    public static void main(String[] args){
        MyThread thread = new MyThread();
        thread.start();
    }

    @Override
    public void run(){
        System.out.println("Hello MyThread!");
    }
}

总结: 继承Thread类重写的是run()方法,不是start()方法,但是占用了继承的名额,由于Java中的类是单继承的,这会导致该线程无法继承其他父类。

实现Runnable接口:

public class MyRunnable implements Runnable{
    public static void main(String[] args){
        Thread thread = new Thread(new MyRunnable());
        thread.start();
    }

    @Override
    public void run(){
        System.out.println("Hello MyRunnable!");
    }
}

总结: 实现Runnable接口,实现run()方法,使用依然要用到Thread,这种方式相比直接继承Thread类,还可以继承其他类,所以这种方法更常用。

实现Callable接口:

public class MyCallable implements Callable<String> {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
        Thread thread = new Thread(futureTask);
        thread.start();
        System.out.println(futureTask.get());
    }

    @Override
    public String call(){
        return"Hello MyCallable!";
    }
}

总结: 实现Callable接口需要实现call()方法,得使用Thread+FutureTask配合,这种方法可以拿到异步执行任务的结果。

Java线程是调用什么方法来启动,为什么?

Java线程是通过调用线程的start()方法来启动的。当创建了一个线程对象后,该线程并不会自动开始执行,而是处于一种新建状态。为了启动线程并执行线程run()方法中的代码,需要先调用该线程的start()方法,并且对于一个线程对象,start()方法只能被执行一次
调用start()方法实际上是在告诉JVM,我们希望启动一个新的线程来执行该线程对象中的run()方法。start()方法内部会进行一些必要的初始化工作,如分配系统资源,并准备将线程放入就绪状态。一旦线程获得CPU时间片,就会从就绪状态进入运行状态,开始执行run()方法中的代码。
需要注意: run方法仅仅是线程类中的一个普通方法而已。调用run()方法并不会创建一个新的线程,而只是在当前线程中执行了run()方法而已,这就像调用普通的方法一样。

Java线程有哪些常用的调度方法?

Java线程常用的调度方法一般有线程等待、线程通知、线程休眠、线程让步、线程中断五种。
线程等待: 当前线程调用Object类的wait() 方法后,会使线程进入等待状态,直到其他线程调用此线程对象的notify()notifyAll() 方法来唤醒它。这个方法通常用在多线程同步中,以确保线程按照特定的顺序访问共享资源。wait方法也可以有超时参数timeout,如果线程调用这个方法后,没有在指定的timeout时间内被唤醒,那么这个方法会因为超时返回

  • 在线程等待中还有一个**join()**方法,它能够让父线程等待子线程结束之后继续执行,即当我们调用某个线程的join()方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行

线程通知: 一个线程可以通过调用Object类的notify()notifyAll() 方法来唤醒在该对象上等待的其他线程。当调用的是notify()方法时,如果此时有多个线程在此对象上等待,则会随机唤醒一个线程,而notifyAll()则是唤醒此对象上等待的所有线程。
线程休眠: 通过调用Thread类下的sleep(long) 方法,使当前线程转到超时等待阻塞状态,long参数设定睡眠的时间,以毫秒为单位。当睡眠结束后,线程则会自动转为就绪状态。
线程让步: 通过调用Thread类下的yield() 方法,暂停当前正在执行的线程对象,把执行的机会让给相同或更高优先级的线程。
线程中断: 通过调用Thread类下的interrupt() 方法,将该线程的中断标志为设为true。中断的结果线程是死亡,还是等待新的任务或是继续运行下一步,就取决于程序本身。同时可以通过调用isInterrupted() 或是interrupted() 方法去判断某个线程是否已被发送过中断请求,其中isInterrupted() 方法不会清除中断标志位,而interrupted() 方法如果发现当前线程被中断,则会清除线程中断标记,并将中断标记设置为false

Java线程有多少种状态?

Java线程的状态分为初始状态、运行状态(可以分为就绪和运行中)、阻塞状态、等待状态、超时等待和终止状态六种状态。
初始状态 (NEW):线程被构建,但是还没有调用 start 方法;
运行状态 (RUNNABLE):该状态代表线程已经准备运行或者正在运行。一般在调用 start() 方法后,该线程就处于该状态 ;
阻塞状态 (BLOCKED):这种状态一般发生在多个线程进行工作时,假如有两个线程:线程1和线程2。当通过先启动线程1后启动线程2时候。此时的线程1处于运行状态,而线程2处于阻塞状态;
等待状态 (WAITING):线程在调用其它线程的join()方法、调用wait()方法等操作时,会使该线程会进入等待状态。进入这个状态后的线程需要等待其他线程做出一些特定动作(通知或中断)。
超时等待状态 (TIMED_WAITING):超时等待状态用在于线程使用 sleep() 方法时,线程就处于超时等待状态。直到 sleep() 方法执行完毕,线程才会被唤醒。
终止状态 (TERMINATED):当线程执行完毕。这个线程就死亡了,此时就是终止状态。
在这里插入图片描述
图片来源:https://blog.csdn.net/qq_33996921/article/details/106357703

什么是线程上下文切换?

线程上下文切换指的是在多线程运行时,操作系统从当前正在执行的线程中保存它的上下文信息(包括当前线程的寄存器、程序指针、栈指针等状态信息),并将另一个等待执行的线程的上下文信息恢复到该线程中,从而实现线程直接的切换。

线程有哪些通信方式?

线程间通信是指在多线程编程中,各个线程之间共享信息或者协同完成某一任务的过程。常用的线程间通信方式一般有以下几种:
1.共享变量:共享变量是指多个线程都可以访问和修改的变量。它们通常是在主线程中创建的。多个线程对同一个共享变量进行读写操作的时候,可能会导致数据错误或程序异常。需要使用同步机制如synchronized、Lock等来保证线程安全;
2.管道通信:管道是一种基于文件描述符的通信机制,形成一个单向通信的数据流管道。它通常用于只有两个进程或线程之间的通信。其中一个进程将数据写入到管道(管道的输出端口),另一个进程从管道的输入端口读取数据;
3.信号量:信号量(semaphore)是一种计数器,用于控制多个线程对资源的访问。当一个线程需要访问资源时,它需要申请获取信号量,如果信号量的计数器大于0,则可以访问资源,否则该线程就会等待。当线程结束访问资源后,需要释放信号量,并将计数器加1;
4.条件变量: 条件变量是一种通知机制,用于在多个线程之间传递状态信息和控制信息。当某个线程需要等待某个条件变量发生改变时,它可以调用**wait()方法挂起,并且释放所占用的锁。当某个线程满足条件后,可以调用notify()或者signal()**方法来通知等待该条件变量的线程继续执行。

标签:状态,八股,调用,java,Thread,并发,线程,执行,方法
From: https://blog.csdn.net/m0_46008105/article/details/136811718

相关文章

  • Java毕业设计-基于SSM框架的学生成绩管理系统项目实战(附源码+论文)
    大家好!我是岛上程序猿,感谢您阅读本文,欢迎一键三连哦。......
  • Java中的多线程是如何实现的?
    ​​​​​​继承Thread类:通过继承Java的Thread类并重写其run()方法,可以创建一个线程。run()方法包含了线程要执行的代码。创建Thread子类的实例,并调用其start()方法来启动线程。start()方法会导致线程开始执行,自动调用run()方法。注意:Java不支持多重继承,因此如果类已经继承了......
  • Java中的泛型是如何工作的?
    Java中的泛型(Generics)是JDK5.0引入的一个新特性,它提供了编译时类型安全,允许在定义类、接口和方法时使用类型参数(typeparameters)。泛型的主要目的是在编译时增强类型检查,以减少运行时类型转换的错误,同时保持使用泛型类型时的类型灵活性。以下是Java中泛型工作的几个关键点:类......
  • 计算机毕业设计-基于Java+SSM架构的学生综合考评管理系统项目开发实战(附论文+源码)
    大家好!我是职场程序猿,感谢您阅读本文,欢迎一键三连哦。......
  • 程序人生——Java开发持续进阶,拥抱开源世界以思想为源泉
    目录引出开源世界建议139:大胆采用开源工具建议140:推荐使用Guava扩展工具包建议141:Apache扩展包建议142:推荐使用Joda日期时间扩展包建议143:可以选择多种Collections扩展思想为源建议144:提倡良好的代码风格建议145:不要完全依靠单元测试来发现问题建议146:让注释正确、清......
  • 程序人生——Java使用关于性能和效率的建议
    目录引出性能和效率建议132:提升Java性能的基本方法建议133:若非必要,不要克隆对象建议134:推荐使用“望闻问切”的方式诊断性能建议135:必须定义性能衡量标准建议136:枪打出头鸟—解决首要系统性能问题建议137:调整JVM参数以提升性能建议138:性能是个大“咕咚”深入认识JVM......
  • 史上最全Java核心面试题(带全部答案)2024年最新版
    今天要谈的主题是关于求职,求职是在每个技术人员的生涯中都要经历多次。对于我们大部分人而言,在进入自己心仪的公司之前少不了准备工作,有一份全面细致面试题将帮助我们减少许多麻烦。在跳槽季来临之前,特地做这个系列的文章,一方面帮助自己巩固下基础,另一方面也希望帮助想要换工......
  • Java 基础语法(2)
    一、流程控制结构1.分支结构if语句if(条件){语句;}elseif(条件){语句;}else{语句;}switch语句switch(变量){case"":语句;break;case"":case"":case"":……语句;break;default:语句;}2.循环结构for循环for(初始化语句......
  • 为 java 开发者设计的性能测试框架,用于压测+测试报告生成
    拓展阅读junit5系列教程基于junit5实现junitperf源码分析Autogeneratemockdataforjavatest.(便于Java测试自动生成对象信息)Junitperformancerelyonjunit5andjdk8+.(java性能测试框架。压测+测试报告生成。)junitperfjunitperf是一款为java开发者设......
  • Java 入门 - 常用的dos命令
    切换盘符盘符名:->回车查看当前路径下的文件或者文件夹dir进入指定文件夹下cd文件夹名字进入到多级文件夹下cd文件夹名字\文件夹名字退到上一级目录cd..或者cd..直接退到磁盘位置(退至根目录)cd\或者cd\清屏cls 退出黑窗口 exit......