多线程面试题总结

 什么是线程:
    * 线程是程序执行的一条路径,一个进程中可以包含多条线程
    * 多线程并发执行可以提高程序的效率,可以同时完成多项工作


多线程的应用场景:
    * 迅雷开启多条线程一起下载
    * QQ同时和多个人一起视频
    * 服务器同时处理多个客户端请求

 

多线程并行和并发的区别
* 并行就是两个任务同时运行,就是甲任务进行的同时,乙任务也在进行(需要多核CPU)
* 并发是指两个任务都请求运行,而处理器只能接受一个任务,就把这两个任务安排轮流进行,由于时间间隔较短,
  使人感觉两个任务都在运行
* 举例:我跟两个网友聊天,左手操作一个电脑跟甲聊,同时右手用另一台电脑跟乙聊天,这就叫并行
* 如果用一台电脑我先给甲发个消息,然后立刻再给乙发消息,然后再跟甲聊,再跟乙聊,这就叫并发

Java程序运行原理和JVM的启动是多线程的吗
* A:Java程序运行原理:
    * Java命令会启动java虚拟机,启动JVM等于启动了一个应用程序,也就是启动了一个进程,
      该进程会自动启动一个"主线程",然后主线程去调用某个类的main方法
    
* B:JVM的启动是多线程的吗
    * JVM启动至少启动了垃圾回收线程和主线程,所以是多线程的

多线程程序实现的方式1
.继承Thread类
    * 定义类继承Thread
    * 重写run方法
    * 把新线程要做的事写在run方法中
    * 创建线程对象
    * 开启新线程,内部会自动执行run方法
2.实现Runnable接口
    * 定义类实现Runnable接口
    * 实现run方法
    * 把新线程要做的事写在run方法中
    * 创建自定义的Runnable的子类对象
    * 创建Thread对象,传入Runnable
    * 调用start()开启新线程,内部会自动调用Runnable的run()方法
    
* a.继承Thread:由于子类重写了Thread类的run(),当调用start()时,直接找子类的run()方法
* b.实现Runnable:构造函数中传入了Runnable的引用,成员变量记住了它,start()调用run()方法时,
      内部判断成员变量Runnable的引用是否为空,不为空编译时看的是Runnable接口的run()方法,
          运行时执行的是接口实现类的run()方法

两种方式的区别
* 继承Thread
    * 好处是:可以直接使用Thread类中的方法,代码简单
    * 弊端是:如果已经有了父类,就不能用这种方法
* 实现Runnable接口
    * 好处是:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口,而且接口是可以多实现的
    * 弊端是:不能直接使用Thread中的方法需要先获取到线程对象后,才能得到Thread的方法,代码相对复杂

获取名字和设置名字
* 1.获取名字:
    * 通过getName()方法获取线程对象的名字//默认从Thread-0开始命名,下一个为Thread-1
* 2.设置名字:
    * 通过构造函数可以传入String类型的名字:,或者通过setName(String)方法可以设置线程对象的名字

获取当前线程的对象
 Thread.currentThread(),主线程也可以获取

同步代码块
* 1.什么情况下需要同步:
    * 当多线程并发,有多段代码同时执行时,我们希望某一段代码执行的过程中,CPU不要切换到其他线程工作,
      这时就需要同步,
    * 如果两段代码是同步的,那么同一时间只能执行一段,在一段代码没执行结束之前,不会执行另外一段代码
* 2.同步代码块:
    * 使用synchronized关键字加上一个锁对象来定义一段代码,这就叫同步代码块,
    * 多个同步代码块,如果使用相同的锁对象,那么他们就是同步的,

同步方法
* 使用synchronized关键字修饰一个方法,该方法中所有的代码都是同步的
* 非静态的同步方法的锁对象是this,静态的同步方法的锁对象是该类的字节码对象

总结:非静态同步函数的锁是:this,演示时用一个同步方法,一个同步代码块但是锁对象不是this,如其他类对象d或者字节码
对象作为锁都会乱序,而用this作为锁就不会乱序,说明同步代码块用this作为锁时跟非静态同步方法的锁,是同一把锁;
同理,静态的同步函数的锁是:本类字节码对象,只有同步方法用同一个字节码对象时,才不会乱序,他们的锁是同一把锁!

线程安全问题
* 多线程并发操作同一数据时,就有可能出现线程安全问题,如出现票数为负数,为0的情况
* 使用同步技术可以解决这种问题,把操作数据的代码进行同步,不要多个线程一起操作

用同步代码块时要保证是同一把锁,如果用继承线程类创建四个线程时this对象都不同,而用实现Runnable接口时,虽然
也创建了四个线程类对象,但是传入构造的都是同一个Runnable对象引用即this,所以为了避免这种麻烦,以后用同步代码块时,
锁对象最好用同步代码块所在类的字节码对象,这样可以保证是同一把锁,或者在同步代码块所在类定义一个静态成员变量,如
private static Object obj = new Object();用obj作为锁,但是麻烦,所以,统一用同步代码块所在类的字节码对象做同步锁
但是,如果用的是同步方法就要分情况了,非静态同步方法的锁对象是this,而静态同步方法的锁对象是该类的字节码对象!!!


两个线程间的通信
* 1.什么时候需要通信
    * 多个线程并发执行时,在默认情况下CPU是随机切换线程的,
    * 如果我们希望他们有规律的执行,就可以使用通信,例如让每个线程执行一次打印
* 2.怎么通信
    * 如果希望线程等待,就调用wait(),释放锁,
    * 如果希望等待的线程唤醒,就调用notify();
    * 注意这两个方法必须在同步代码中执行,并且使用同步锁对象来调用,这两个前提条件要特别注意,否则运行报异常!

三个或三个以上间的线程通信
* 多个线程通信的问题
    * notify()方法是随机唤醒一个线程,
    * notifyAll( )方法是唤醒所有线程,
    * JDK5之前无法唤醒指定的一个线程,(JDK5之后有新特性即下个知识点的互斥锁的条件调用方法来解决唤醒指定线程)
    * 如果多个线程之间通信,需要使用notifyAll()通知所有线程,用while来反复判断标记条件,而不再用if判断
总结:跟两个线程间的通信相比,无非改了标记判断语句为while,还有唤醒用的是锁对象调用notifyAll()方法而不再是notify
另外,线程间的通信注意的问题如下:
1,在同步代码块中,用哪个锁对象,就用哪个锁对象调用wait方法

2,为什么wait方法和notify方法定义在Object这类中?
答:因为锁对象可以是任意对象,Object是所有的类的基类,所以wait方法和notify方法需要定义在Object这个类中

3,sleep方法和wait方法的区别?
答:第一,sleep方法必须传入参数,参数就是时间,时间到了自动醒来,
而wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待;
第二,sleep方法在同步函数或同步代码块中,不释放锁,睡着了也抱着锁睡,
而wait方法在同步函数或者同步代码块中,释放锁

线程的五种状态
* 新建,就绪,运行,阻塞,死亡

A.线程的五种状态分别是新建,就绪,运行,阻塞,死亡
B.新建状态,创建了线程对象
C.就绪状态,线程对象启动,但是没有获得CPU的执行权
D.运行状态获取到了CPU的执行权
E.阻塞状态,没有CPU的执行权,会回到就绪状态
F.死亡状态,代码运行完毕,线程消亡

* 线程池概述:
    * 程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互,而使用线程池可以很好的提高性能,
      尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池,线程池里的每一个线程代码结束后,
      并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值