人生几何?

java 多线程T(重写) --- 2---2021-09-07

2021-09-06  本文已影响0人  鄙人_阿K

《面试题对标大纲》

题目列表集

1、线程的状态
2、Java 中用到的线程调度算法是什么?
3、 线程的调度策略
4、什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing )?
5、请说出与线程同步以及线程调度相关的方法。
6、sleep() 和 wait() 有什么区别?
7、你是如何调用 wait() 方法的?使用 if 块还是循环?为什么?
8、为什么线程通信的方法 wait(), notify()和 notifyAll()被定义在 Object 类里?
9、为什么 wait(), notify()和 notifyAll()必须在同步方法或者同步块中被调用?
10、Thread 类中的 yield 方法有什么作用?
11、为什么 Thread 类的 sleep()和 yield ()方法是静态的?
12、线程的 sleep()方法和 yield()方法有什么区别?
13、如何停止一个正在运行的线程?
14、 Java 中 interrupted 和 isInterrupted 方法的区别?
15、什么是阻塞式方法?
16、Java 中你怎样唤醒一个阻塞的线程?
17、notify() 和 notifyAll() 有什么区别?
18、如何在两个线程间共享数据?
19、 Java 如何实现多线程之间的通讯和协作?
20、同步方法和同步块,哪个是更好的选择?

1、线程的状态

image.png

2、Java 中用到的线程调度算法是什么?

  1. 计算机通常只有一个 CPU,在任意时刻只能执行一条机器指令,每个线程只有获得CPU 的使用权
    才能执行指令。所谓多线程的并发运行,其实是指从宏观上看,各个线程轮流获得 CPU 的使用
    权,分别执行各自的任务。在运行池中,会有多个处于就绪状态的线程在等待 CPU,JAVA 虚拟机
    的一项任务就是负责线程的调度,线程调度是指按照特定机制为多个线程分配 CPU 的使用权。
    (Java是由JVM中的线程计数器来实现线程调度)

  2. 有两种调度模型:分时调度模型和抢占式调度模型。

3、 线程的调度策略

线程调度器选择优先级最高的线程运行,但是,如果发生以下情况,就会终止线程的运行:
(1)线程体中调用了 yield 方法让出了对 cpu 的占用权利
(2)线程体中调用了 sleep 方法使线程进入睡眠状态
(3)线程由于 IO 操作受到阻塞
(4)另外一个更高优先级线程出现
(5)在支持时间片的系统中,该线程的时间片用完

4、什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing )?

5、请说出与线程同步以及线程调度相关的方法。

(1) wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;
(2)sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理
InterruptedException 异常;
(3)notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一
个等待状态的线程,而是由 JVM 确定唤醒哪个线程,而且与优先级无关;
(4)notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它
们竞争,只有获得锁的线程才能进入就绪状态;

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

相同:

两者都可以暂停线程的执行

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

synchronized (monitor) { 
       // 判断条件谓词是否得到满足 
       while(!locked) { 
          // 等待唤醒 
          monitor.wait();
        }
        // 处理其他的业务逻辑
 }

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

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

当一个线程需要调用对象的 wait()方法的时候,这个线程必须拥有该对象的锁,接着它就会释放这
个对象锁并进入等待状态直到其他线程调用这个对象上的 notify()方法。同样的,当一个线程需要
调用对象的 notify()方法时,它会释放这个对象的锁,以便其他在等待的线程就可以得到这个对象
锁。由于所有的这些方法都需要线程持有对象的锁,这样就只能通过同步来实现,所以他们只能在
同步方法或者同步块中被调用。

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

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

Thread 类的 sleep()和 yield()方法将在当前正在执行的线程上运行。所以在其他处于等待状态的线
程上调用这些方法是没有意义的。这就是为什么这些方法是静态的。它们可以在当前正在执行的线
程中工作,并避免程序员错误的认为可以在其他非运行线程调用这些方法。

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

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

13、如何停止一个正在运行的线程?

1、使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。(比如循环内的状态 flag)
2、使用stop方法强行终止,但是不推荐这个方法,因为stop和suspend及resume一样都是过期
作废的方法。
3、使用interrupt方法中断线程。(Thread 类下)

14、 Java 中 interrupted 和 isInterrupted 方法的区别?

  1. interrupt:用于中断线程。调用该方法的线程的状态为将被置为”中断”状态。
    注意:线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态为并做处
    理。支持线程中断的方法(也就是线程中断后会抛出interruptedException 的方法)就是在监视线程的
    中断状态,一旦线程的中断状态被置为“中断状态”,就会抛出中断异常。

  2. interrupted:是静态方法,查看当前中断信号是true还是false并且清除中断信号。如果一个线程
    被中断了,第一次调用 interrupted 则返回 true,第二次和后面的就返回 false 了。

  3. isInterrupted:是可以返回当前中断信号是true还是false,与interrupt最大的差别

15、什么是阻塞式方法?

阻塞式方法是指程序会一直等待该方法完成期间不做其他事情,ServerSocket 的accept()方法就是
一直等待客户端连接。这里的阻塞是指调用结果返回之前,当前线程会被挂起,直到得到结果之后
才会返回。此外,还有异步和非阻塞式方法在任务完成前就返回。

16、Java 中你怎样唤醒一个阻塞的线程?

17、notify() 和 notifyAll() 有什么区别?

1、如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去
竞争该对象的锁。
2、notifyAll() 会唤醒所有的线程,notify() 只会唤醒一个线程。
3、notifyAll() 调用后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,
4、如果不成功则留在锁池等待锁被释放后再次参与竞争。而 notify()只会唤醒一个线程,具体唤醒哪
一个线程由虚拟机控制。

18、如何在两个线程间共享数据?

在两个线程间共享变量即可实现共享。

一般来说,共享变量要求变量本身是线程安全的,然后在线程内使用的时候,如果有对共享变量的复合操作,那么 也得保证复合操作的线程安全性。

19、 Java 如何实现多线程之间的通讯和协作?

  1. 可以通过中断 和 共享变量的方式实现线程间的通讯和协作
  2. 比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放
    入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权。因为生产者如果不
    释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产
    者就会一直无限等待下去。因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用
    权,并进入挂起状态。然后等待消费者消费了商品,然后消费者通知生产者队列有空间了。同样
    地,当队列空时,消费者也必须等待,等待生产者通知它队列中有商品了。这种互相通信的过程就
    是线程间的协作。
  3. Java中线程通信协作的最常见方式:
  1. 线程间直接的数据交换:通过管道进行线程间通信:字节流、字符流

20、同步方法和同步块,哪个是更好的选择?

1、同步块是更好的选择,因为它不会锁住整个对象(当然你也可以让它锁住整个对象)。同步方法会
锁住整个对象,哪怕这个类中有多个不相关联的同步块,这通常会导致他们停止执行并需要等待获
得这个对象上的锁。
2、同步块更要符合开放调用的原则,只在需要锁住的代码块锁住相应的对象,这样从侧面来说也可以
避免死锁。
▲ 请知道一条原则:同步的范围越小越好。

上一篇 下一篇

猜你喜欢

热点阅读