多线程基础面试题

并发编程三个必要因素是什么:

  • 原子性:原子,即一个不可再被分割的颗粒。原子性指的是一个或多个操作要么全部执行成功要么
    全部执行失败。
  • 可见性:一个线程对共享变量的修改,另一个线程能够立刻看到。(synchronized,volatile)
  • 有序性:程序执行的顺序按照代码的先后顺序执行。(处理器可能会对指令进行重排序)

Java 程序中怎么保证多线程的运行安全

  • 线程切换带来的原子性问题 解决办法:使用多线程之间同步synchronized或使用锁(lock)。
  • 缓存导致的可见性问题 解决办法:synchronized、volatile、LOCK,可以解决可见性问题
  • 编译优化带来的有序性问题 解决办法:使用volatie关键字禁止指令重排

创建线程的四种方式

  1. 继承Thread类
  2. 实现Runnable接口
  3. 实现Callable接口
  4. 使用匿名内部类

Runnable和Callable接口的区别

  1. Runnable 接口 run 方法无返回值;Callable 接口 call 方法有返回值,是个泛型,和Future、
    FutureTask配合可以用来获取异步执行的结果
  2. Runnable 接口 run 方法只能抛出运行时异常,且无法捕获处理;Callable 接口 call 方法允许抛出
    异常,可以获取异常信息 注:Callalbe接口支持返回执行结果,需要调用FutureTask.get()得到,
    此方法会阻塞主进程的继续往下执行,如果不调用不会阻塞。

为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用run() 方法?

直接执行 run() 方法,会把 run 方法当成一个 main 线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。

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


线程的状态:新建、就绪、运行、阻塞、死亡


java的线程调度算法:分时调度,抢占式


sleep() 和 wait() 有什么区别?

  1. sleep() 是 Thread线程类的静态方法,wait() 是 Object类的方法。
  2. sleep() 不释放锁;wait() 释放锁。
  3. Wait 通常被用于线程间交互/通信,sleep 通常被用于暂停执行。
  4. wait() 方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的 notify()或者 notifyAll() 方法。sleep() 方法执行完成后,线程会自动苏醒。或者可以使用wait(longtimeout)超时后线程会自动苏醒。

你是如何调用 wait() 方法的?使用 if 块还是循环?为什么?

处于等待状态的线程可能会收到错误警报和伪唤醒,如果不在循环中检查等待条件,程序就会在没有满足结束条件的情况下退出。所以应该使用循环调用


为什么线程通信的方法 wait(), notify()和 notifyAll()被定义在 Object 类里?

因为Java所有类的都继承了Object,Java想让任何对象都可以作为锁,并且 wait(),notify()等方法用于等待对象的锁或者唤醒线程,在 Java 的线程中并没有可供任何对象使用的锁,所以任意对象调用方法一定定义在Object类中。


为什么 wait(), notify()和 notifyAll()必须在同步方法或者同步块中被调用?

在使用wait()方法的时候会释放对象锁,使用notify()和notifyAll()也会释放锁,所以说必须持有锁才能释放锁,所以只能在同步代码块中


Thread 类中的 yield 方法有什么作用?

使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。


为什么 Thread 类的 sleep()和 yield ()方法是静态的?

因为他们只能在运行中的线程中使用,如果是非静态的,那么未运行的线程也就可以调用了,就会出现错误


线程的 sleep()方法和 yield()方法有什么区别?

  1. sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
  2. 线程执行 sleep()方法后转入阻塞(blocked)状态,而执行 yield()方法后转入就绪(ready)状态;
  3. sleep()方法声明抛出 InterruptedException,而 yield()方法没有声明任何异常;
  4. sleep()方法比 yield()方法(跟操作系统 CPU 调度相关)具有更好的可移植性,通常不建议使用yield()方法来控制并发线程的执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值