[Java面试题]——多线程

最近在准备java的面试,在知乎上找到一篇非常好的回答,但是又不想让他在收藏夹里吃灰,所以果断开一个专题来记录里面提到的问题,如果大家也在准备java面试或者想对java有更深的理解,也可以去看看,链接如下:https://www.zhihu.com/question/27858692/answer/787505434
下面的内容都是为了我方便记忆,基本都是照搬,所以大家想看的话直接看链接就好了

并行、并发

并行:同一个时刻,有多个进程同时运行
并发:在一个时间段内,宏观上看有多个进程同时运行,但微观上看,每个时刻只有一个进程在运行

进程、线程

进程是程序运行和资源分配的基本单位,一个程序至少有一个进程,一个进程至少有一个线程。进程在执行的过程中拥有独立的内存单元,多个线程共享内存资源。
线程是进程的实体,是CPU调度和分配的基本单位。同一进程中的多个线程之间可以并发执行。

线程创建的方式

  • 继承Thread类创建线程类
    定义Thread类的子类,并重写该类的run方法。方法体里代表了线程要完成的任务,因此run方法称为执行体
    创建Thread子类的实例,即创建线程对象
    调用线程对象的start()方法来启动线程
  • 通过Runnable接口创建线程类
    定义Runnable接口的实现类,并重写改接口的run()方法
    创建Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象
    调用线程对象的start()方法启动线程

线程的状态

创建、就绪、运行、阻塞、死亡

  • 创建:生成线程对象,并且没有调用该对象的start()方法
  • 就绪:调用线程的start()方法后,线程进入就绪状态,但此时,线程调度程序还没有吧该线程设置为当前线程,所以出于就绪状态。同时,线程从运行状态以及阻塞状态回来都可处于就绪状态
  • 运行:线程调度程序将该线程设置为当前线程,开始执行其run函数里的代码
  • 阻塞:线程运行期间,由于等待某个事件的发生,将线程挂起
  • 死亡:该线程的run方法执行结束或者调用stop方法后,线程就会死亡,无法再次进入就绪状态

sleep() 和 wait() 的区别

  • sleep() :是线程类的静态方法,让线程进入睡眠状态,将执行机会让给其他线程,待休眠时间结束以后,线程进入就绪状态和其他线程一起竞争CPU。由于该方法是一个静态的方法,所以当一个synchronized块中调用了该方法,线程虽然进入休眠状态,但其他的线程无法访问该对象
  • wait() :是Object类的方法,让线程进入到一个和该对象相关的等待池,同时释放对象锁,使得其他线程能够访问,并且可以通过notify、notifyAll方法来唤醒等待的线程

notify() 和 notifyAll() 的区别

当线程调用了wait方法,就会进入该对象的等待池中,不能去竞争该对象的锁

  • 当有线程调用了notifyAll()方法【唤醒所有的wait线程】或notify()方法【随机唤醒一个wait线程】,被唤醒的线程会进入该对象的锁池中去竞争对象锁。
  • 优先级高的线程竞争到对象锁的概率越大,竞争到对象锁的线程执行完synchronized代码块后,会释放该对象锁,锁池中的线程会继续竞争

线程的run() 和 start() 有什么区别

方法run() 称为线程体。调用Thread类的start()方法来启动线程

线程池的创建方法

  • newFixedThreadPool (int nThreads)
    创建固定长度的线程池,每当提交一个任务就创建一个线程,直到线程池的最大数量,当线程发生错误而结束时,线程池会补充一个新的线程

  • newCachedThreadPool ()
    创建一个可缓存的线程池,如果线程池的规模超过了处理需求,将自动回收空闲线程,当需求增加时,自动添加新线程,规模不存在限制

线程池的状态

Running 、ShutDown 、Stop 、Tidying 、Terminated

java如何保证多线程的运行安全

线程安全在三个方面体现:

  • 原子性:提供互斥访问,同一时刻只能有一个县城对数据进行操作
  • 可见性:一个线程对主内存的修改可以及时的被其他线程看到
  • 有序性:一个线程观察其他线程中指令执行顺序,由于指令重排序,该观察结果一般杂乱无序

死锁预防

死锁形成的四个必要条件:

  • 互斥:已经分配给进程的资源不能被其他进程访问,只能等待占有该资源的进程释放该资源
  • 请求和保持:进程在等待其他资源时,对于已经获得资源不予释放
  • 不可剥夺:操作系统不能剥夺进程已经获得的资源,只能由进程主动释放
  • 资源循环等待:要发生死锁,必然出现资源的循环的等待环路

你可能感兴趣的:(Java)