Java练习题 · 多线程篇

  • 1️⃣ 多线程篇
  • 2️⃣ 答案

1️⃣ 多线程篇

一、填空题

  1. Java 多线程可以依靠________ 、________ 和________ 三种方式实现。
  2. 多个线程操作同一资源的时候需要注意________,依靠________ 关键字实现,实现手段是:________ 和________,过多的使用,则会出现________ 问题。
  3. Java 程序运行时,至少启动________ 个线程,分别是________ 和________ 。
  4. main 线程的优先级是________ 。
  5. 线程在生命周期中要经历五种状态,分别是________状态、________状态、________状态、________状态和________状态。
  6. Object类提供的________ 、________ 和________ 三个方法可以控制线程。

二、选择题

  1. 线程的启动方法是( )。
    A. run()
    B. start()
    C. begin()
    D. accept()

  2. Thread 类提供表示线程优先级的静态常量,代表普通优先级的静态常量是( )。
    A. MAX _PRIORITY
    B. MIN_PRIORITY
    C. NORMAL_PRIORITY
    D. NORM_PRIORITY

  3. 设置线程优先级的方法是( )。
    A. setPriority()
    B. getPriority()
    C. getName()
    D. setName()

  4. Thread 类的 ( )方法是不建议使用的。
    A. stop()
    B. suspend()
    C. resume()
    D. 全部都是

  5. 下列 ( ) 关键字通常用来对对象加锁,从而使得对对象的访问是排他的。
    A. serialize
    B. transient
    C. synchronized
    D. static

三、 判断题

  1. Java 直接调用 Thread 类中的 run(方法可以启动一个线程。 ( )
  2. 进程是在线程的基础之上的进一步划分。 ( )
  3. Java 是多线程的编程语言。 ( )
  4. 不管使用 Callable 还是Runnable 接口实现的多线程最终都需要通过Thread 类启动。 ( )

四、 简答题

  1. 简述线程两种实现方式及区别。
  2. 简述死锁的产生。

五、 编程题

  1. 设计四个线程对象,两个线程执行减操作,两个线程执行加操作。

2️⃣ 答案

一、填空题

  1. 继承Thread类、实现Runnable接口 和使用线程池
  2. 线程安全,synchronized ,实现手段是:同步代码块 和同步方法,过多的使用,死锁
  3. 一个,主线程 和其他由程序创建的线程
  4. 5
  5. 新建状态、就绪状态、运行状态、阻塞状态和终止状态
  6. wait()、notify() 和notifyAll()

二、选择题

  1. ( B )
  2. ( D )
  3. ( A )
  4. ( A )
  5. ( C )

三、 判断题

  1. ( ❌ )
  2. ( ✔️ )
  3. ( ✔️ )
  4. ( ✔️ )

四、 简答题

  1. 简述线程两种实现方式及区别。

    两种线程的实现方式分别是继承Thread类和实现Runnable接口。

    • 继承Thread类:通过继承Thread类并重写其run()方法来创建线程。这种方式相对简单,但由于Java只支持单继承,因此如果已经继承了其他类,则不能再直接使用该方式创建线程。

    • 实现Runnable接口:通过实现Runnable接口,并实现其run()方法来创建线程。这种方式更加灵活,因为Java支持多个接口的实现。同时,可以将Runnable对象传递给Thread类的构造函数,在需要时创建线程。

    区别:

    • 继承Thread类的方式限制了单继承的特性,因为一个类只能继承一个父类。但它可以通过重写Thread类的方法来定义线程的行为。
    • 实现Runnable接口的方式克服了单继承的限制,因为它允许类实现多个接口,并将实现了Runnable接口的类作为参数传递给Thread类的构造函数。
    • 使用Runnable接口的方式更加常见和推荐,因为它可以更好地符合面向对象的设计原则,将线程的任务与线程本身进行解耦。
  2. 简述死锁的产生。

    死锁是指多个线程因相互等待对方所持有的资源而无法继续执行的情况。死锁的产生通常涉及以下四个条件:

    • 互斥条件:至少有一个资源被多个线程排他性地持有,即一次只能由一个线程使用。
    • 请求与保持条件:一个线程在持有了部分资源的同时,继续请求其他资源。
    • 不可剥夺条件:已经分配给一个线程的资源不能被强制性地剥夺。
    • 循环等待条件:存在一个等待循环,每个线程都等待下一个线程所持有的资源。

    当以上条件同时满足时,就可能引发死锁现象。当多个线程都在等待获取对方所拥有的资源,而无法释放自己持有的资源时,就会陷入死锁状态,程序无法继续执行下去。

五、 编程题

  1. 代码如下:
    public class AddSubThread implements Runnable {private static int number = 0;private int operation;public AddSubThread(int operation) {this.operation = operation;}@Overridepublic void run() {if (operation == 0) {for (int i = 0; i < 5; i++) {synchronized (AddSubThread.class) {number++;System.out.println("加操作:" + number);}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}} else {for (int i = 0; i < 5; i++) {synchronized (AddSubThread.class) {number--;System.out.println("减操作:" + number);}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}public static void main(String[] args) {// 创建四个线程对象,两个线程执行加操作,两个线程执行减操作Thread t1 = new Thread(new AddSubThread(0));Thread t2 = new Thread(new AddSubThread(0));Thread t3 = new Thread(new AddSubThread(1));Thread t4 = new Thread(new AddSubThread(1));// 启动线程t1.start();t2.start();t3.start();t4.start();}}