线程面试题

1、线程和进程的区别:

        进程:程序由指令和数据组成,指令想要运行,数据想要读写,就必须将指令加载到cpu,

数据加载到内存。在指令运行过程中还需要用到磁盘,网络等设备。进程就是用来加载指令 管理内存 管理io的。进程可以看作时程序的一个实例,大部分的程序可以同时运行多个实例进程,也有的程序只能启动一个实例进程

        线程:一个进程可以分为多个线程。一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给cpu执行。

2、并发和并行的区别:

并发:把任务在不同的时间点交给处理器进行处理  同一时间 任务依次运行

并行:把每个任务分配给每一个处理器独立完成    同一时间 任务一定是同时运行

并发不是并行  并行是让不同的代码片段同时在不同的物理处理器上执行  并行的关键是同时做跟多事情  而并发是值同时管理跟多事情  这些事情可能只做了一半就被暂停去做别的事情了

在很多情况下  并发的效果比并行好,因为操作系统和硬件的总资源一般很少  但能支持系统封同时做很多的事情

3、线程的四种创建方式:

  1. 直接使用Thread
  2. 使用Runnable配合Thread
  3. FutureTask配合Thread
  4. 线程池

4、线程有那些状态:

  1. 新建  new Thread
  2. 可运行状态RUNABLE   调用start方法
  3. 终结状态     run方法中代码执行完毕
  4. 阻塞状态        没有获取锁的线程   当获取锁的线程释放掉锁  重新抢占锁成功----》可运行状态
  5. 等待状态   获取锁的线程  调用锁对象 .wait方法
  6. 有时限的等待 获取锁的线程  调用锁对象 .wait(long)方法  调用线程的sleep方法

5、为什么要使用线程池?

  1. 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务
  2. 可以根据系统的承受能力,调整线程池中工作线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程大约1MB内存,线程开的越多 消耗的内存也就越大,最后死机)

6、线程池的构造方法里几个参数的作用分别是什么?

corePoolSize核心线程数  

 maximumPoolSize最大线程数   

keepAliveTime 生存时间  

 unit  时间单位

  workQueue 工作队列   

 threadFactory线程工厂   

handler拒绝策略

7、线程池流程:

        1、当我们向线程池中添加任务   有核心线程执行任务  如果核心线程都在执行任务,将任务假如到任务队列,等待核心线程执行完任务,从队列中获取任务执行,如果队列已经满了  创建救济线程,有急救线程执行任务,急救线程执行完任务后,如果在keepAliveTime时间内没有任务执行,销毁,如果救济线程也无法创建  则触发拒绝策略

8、线程池拒绝策略有哪些:

        抛异常  

        由调用者执行任务

        丢弃任务

        丢弃最早排队的任务,把新任务添加到工作队列

9、notify()和notifyAll()有什么区别:

        notify  唤醒锁对象等待区随机一个线程

        notifyAll 唤醒锁对象等待区所有的线程

10、wait和sleep的区别:

        相同点:wait() ,wait(long) 和 sleep(long) 的效果都是让当前线程暂时放弃 CPU 的使用权,进入WAITING Time_Waiting 状态

        不同点:

                1、方法归属不同  sleep是thread的静态方法  而wait是Object的成员方法  每个对象都有

                2、醒来时机不同  执行sleep和wait的线程都会在等待相应毫秒后醒来  wait 还可以被notify唤醒 wait如果不唤醒就一致等待下去;他们都可以被打断唤醒

                3、锁特性不同   wait方法必须基于锁对象调用  直接调用报错,而sleep没有限制,wait方法执行后会释放对象锁,允许其他线程获得该对象锁,sleep如果在synchronized代码块中执行,并不会释放对象锁

11、lock锁和synchronized锁区别:

        语法局面   synchronized是关键字  底层是通过c++代码实现锁    synchronized同步代码块执行完毕会自动释放锁     lock是一个接口  用java语言实现  需要手动调用unlock方法释放锁

        功能层面:具备基本的互斥  同步 锁重入功能  ——互斥  同步 重入

Lock 提供了许多 synchronized 不具备的功能  Condition  condition=lock.newCondition();

可以利用条件变量进行await  将线程假如等待队列  

        可以利用条件变量进行condition.signalAll();唤醒等待队列某个线程

        Lock有适合不同场景的实现

12、悲观锁和乐观锁的区别:

        悲观锁的核心代码是synchronized  lock

        思想:只有获取锁的线程才能操作共享变量,每次只有一个线程能获取锁成功,获取锁失败的线程都要进入阻塞队列等待

        线程从可运行到阻塞  再从阻塞到可运行,涉及到上下文切换,如果频繁发生会影响效率

        synchronized和lock在获取锁的时候,如果锁已经被其他线程占用,还会充实几次

乐观锁  乐观锁的代表是Atomiclnteger,使用后cas保证原子性

思想:每次只有一个线程能修改成功共享变量,其他i需改失败的线程不需要阻塞,不断重试,知道成功;由于所有的线程一致运行,不需要阻塞,不牵涉频繁上下问切换  需要多喝cpu的支持cpu大于线程数量 

  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值