21xrx.com
2025-03-31 02:38:08 Monday
文章检索 我的文章 写文章
Java面试中常见的场景题及其解决方法
2023-06-16 19:12:34 深夜i     14     0
Java面试 场景题 跑步锁 死锁 内存泄漏

在Java面试中,经常会遇到各种不同类型的场景题,例如跑步锁、死锁、内存泄漏等等。本文将会介绍一些常见的场景题,并提供相应的解决方法和代码案例。以下是几个常见的场景题:

1. 跑步锁(Deadlock)

跑步锁,即两个或多个线程相互等待的情况,导致程序无法继续执行下去。例如线程A持有锁A,等待锁B,而线程B持有锁B,等待锁A。这种情况下,两个线程将会相互等待,导致程序无法继续执行下去。

解决方法:

使用Lock接口代替synchronized关键字。Lock接口提供了更为灵活的锁操作,可以使用tryLock()方法尝试获取锁,如果无法获取锁则不会产生线程阻塞。

代码示例:

Lock lockA = new ReentrantLock();
Lock lockB = new ReentrantLock();
new Thread(() -> {
  while (true) {
    if (lockA.tryLock()) {
      System.out.println("线程1获得了锁A");
      if (lockB.tryLock()) {
        System.out.println("线程1获得了锁B");
        lockB.unlock();
      }
      lockA.unlock();
      break;
    }
  }
}).start();
new Thread(() -> {
  while (true) {
    if (lockB.tryLock()) {
      System.out.println("线程2获得了锁B");
      if (lockA.tryLock()) {
        System.out.println("线程2获得了锁A");
        lockA.unlock();
      }
      lockB.unlock();
      break;
    }
  }
}).start();

2. 死锁(死循环)

死锁是指当两个或多个线程相互等待时,无法继续执行下去,形成的无限循环等待。通常出现在多个线程同时占用相同的资源或者相互依赖的情况。

解决方法:

使用中断机制。当线程遇到无法继续执行时,可以调用Thread.interrupt()方法进行中断,从而结束死锁。

代码示例:

Thread t1 = new Thread(() -> {
  while (!Thread.currentThread().isInterrupted()) {
    synchronized (lock) {
      System.out.println("线程1获得锁");
      try {
        Thread.sleep(1000);
        lock.wait();
      } catch (InterruptedException e) {
        System.out.println("线程1被中断,结束运行");
        Thread.currentThread().interrupt();
      }
    }
  }
});
Thread t2 = new Thread(() -> {
  while (!Thread.currentThread().isInterrupted()) {
    synchronized (lock) {
      System.out.println("线程2获得锁");
      lock.notify();
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        System.out.println("线程2被中断,结束运行");
        Thread.currentThread().interrupt();
      }
    }
  }
});

3. 内存泄漏

内存泄漏是指程序使用了一些资源,但是无法将其释放,导致系统内存不足,最终导致程序崩溃。

解决方法:

手动释放内存。在程序运行过程中,注意及时释放资源,避免资源被占据而无法释放。

代码示例:

// 创建一个大对象
List bigList = new ArrayList<>(); 
  // 使用完后手动释放内存
  bigList.clear();
  bigList = null;
  
  

评论区

请求出错了