21xrx.com
2024-11-08 22:00:48 Friday
登录
文章检索 我的文章 写文章
Java面试中常见的场景题及其解决方法
2023-06-16 19:12:34 深夜i     --     --
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;

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复