Java面试------多线程

一.线程

1.什么是线程,线程和进程的区别

线程:是进程的一个实体,是CPU调度和分配的基本单位,是比进程更小的可以独立运行的基本单位

进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,是操作系统进行资源分配和调度的一个基本单位.

区别:线程划分尺度小于进程,这使多线程程序拥有高并发性,进程在运行时各自内存单元相互独立;

线程之间内存共享,这是多线程编程可以拥有更好的性能和用户体验

2.创建线程的几种方式

继承Thread类并重写run方法创建线程,实现简单但没法继承其他类

实现Runnable接口并重写run方法,避免了单继承的局限性,编程更加灵活,实现解耦

实现Callable接口并重写call接口,可以获取执行结果的返回值,可以抛出异常

使用线程池创建

3.Runnable和Callable的区别

Runnable接口run方法无返回值,Callable接口call方法有返回值,支持泛型

Runnable接口run方法只能抛出运行时异常,且无法捕获处理,Callable接口call方法可以抛出异常

4.如何启动一个线程,调用start和run方法的区别

线程对象调用run方法不开启线程,仅是对象调用方法 

线程对象调用start方法开启线程,并让jvm调用run方法在开启的线程中执行

调用start方法可以启动线程,并且是的线程进入就绪状态,run方法只是一个普通的thread方法,还是在主线程中执行

5.线程有哪几种状态,以及各个状态之间的切换

第一种是new--->新建状态.没有调用start方法

第二种是Runnable--->就绪状态.调用start方法

第三种是Running--->运行状态.调用run方法

第四种是阻塞状态.阻塞状态是线程因为某种原因放弃CPU的使用权,暂时停止运行,知道线程进去就绪状态,才有机会转入运行状态,阻塞的情况分三种

        1>.等待---通过调用线程的wait()方法,让线程等待某工作的完成

        2>.超时等待---通过调用线程的sleep(),jion()或I/O请求时,线程会进入到阻塞状态,当sleep()状态超时,join()等待线程终止或者超时,或者I/O处理完毕时,线程重新转入就绪状态.

        3>.同步阻塞---线程在获取synchronize同步锁失败(因为锁被其他线程占用),他会进入同步阻塞状态

第五种是dead--->死亡状态:线程执行完或因为异常结束run()方法,该线程结束生命周期

6.线程相关的基本方法

线程等待(wait()):调用wait()方法会释放对象的锁,因此wait()方法一般用在同步方法或者同步方法块

线程睡眠(sleep()):sleep()方法不会释放对象锁

线程让步(yield()):yield()方法会使当前线程让出CPU执行时间片,与其他线程重新竞争时间片

线程中断(interrupt()):中断一个线程,会影响线程内部的一个中断标识位,这个线程并不会因此而改变状态

线程唤醒(notify()):唤醒正在等待的任意一个线程

等待其他线程终止(jion()):j调用oin()方法,会是一个线程进入阻塞状态,直到另一个线程结束

7.wait()和sleep()的区别

        1>.来自不同的类

        wait()来自Object类,sleep()来自Thread类

        2>.锁的释放不同

        wait()会释放锁,sleep()不会释放锁

        3>.使用范围不同

        wait()必须在同步代码块中使用,sleep()可以在任何地方使用

        4>.是否需要捕获异常

        wait()需要捕获异常,sleep()不需要捕获异常

二.线程池

1.为什么需要线程池

在实际使用中,线程是很占用资源的,如果对线程管理不完善的话很容易导致系统出现问题,因此,在大多数并发框架中,都会使用线程池来管理线程.

2.使用线程池管理线程的好处

        1>.使用线程池可以重复利用已有的线程继续执行任务,避免了线程创建和销毁时的损耗

        2>.由于没有线程的损耗,因此可以提高系统的响应速度

        3>.使用线程池可以合理的管理线程,根据系统的承受能力调整可运行的线程数量的大小等。

3.线程池的分类

newCachedThreadPool: 创建一个可进行缓存重复利用的线程池
newFixedThreadPool: 创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程,线程池中的线程处于一定的量,可以很好的控制线程的并发量
newSingleThreadExecutor : 创 建一个使用单个worker线程的Executor ,以无界队列方式来运行该线程。线程池中最多执行一个线程,之后提交的线程将会排在队列中以此执行
newSingleThreadScheduledExecutor: 创建一个单线程执行程序,它可安排在给定延迟后运 行命令或者定期执行
newScheduledThreadPool: 创建一个线程池,它可安排在给定延迟后运行命令或者定期的执行
newWorkStealingPool: 创建一个带并行级别的线程池,并行级别决定了同一时刻最多有多少个线程在执行,如不传并行级别参数,将默认为当前系统的 CPU 个数

4.核心参数

corePoolSize:核心线程池的大小

maximumPoolSize:线程池能创建线程的最大个数

keepAliveTime:空闲线程存活时间

unit:时间单位

workQueue:阻塞队列,用于保存任务的阻塞队列

threadFactory:创建线程的工厂类

handler:饱和策略(拒绝策略) 

5.线程池的原理

 线程池的工作过程如下:

当一个任务提交到线程池之后

         1>.线程池判断核心线程池是否已经满了,不是的话创建线程执行当前任务,否则进入2>

         2>.判断阻塞队列是否已经满了,没满放到阻塞对列,否则进入3>

         3>.判断线程池里的线程是否都在执行任务,如果不是,创建一个线程执行任务,否则交给饱和策略来处理任务

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值