编程Java开发人员

在Java中,线程(thread)是什么,它是如何创建和结束的,以及在实现多线程程序时需要考虑哪些细节?

用 Hintsage AI 助手通过面试

答案。

问题历史:

Java自始至终支持多线程。线程允许并行执行多个任务,充分利用多核处理器。JVM提供了对操作系统线程的抽象层。

问题:

创建、管理和结束线程需要清晰理解它们的生命周期、同步和可能的竞争状态。不当使用线程可能导致死锁、对资源的错误访问和复杂的错误日志。

解决方案:

在Java中,可以通过扩展Thread类或实现Runnable接口,或使用现代工具如ExecutorService来创建线程。正确结束线程、管理它们的生命周期和同步访问共享数据是非常重要的。

创建和结束线程的示例:

class MyRunnable implements Runnable { public void run() { System.out.println("线程正在运行"); } } public class ThreadExample { public static void main(String[] args) { Thread t = new Thread(new MyRunnable()); t.start(); // 启动线程 try { t.join(); // 等待结束 } catch (InterruptedException e) { e.printStackTrace(); } } }

关键特性:

  • 必须使用start()方法启动线程,而不是run()(否则不会真正并行)
  • 正确结束时必须使用join()
  • 已结束的线程不能重新启动:新的start会抛出IllegalThreadStateException

反常问题。

结束后能否重新启动线程?

不能。线程在结束后被视为“死”,再次调用start()会导致IllegalThreadStateException

调用t.run()和t.start()有什么区别?

t.run()只是在线程中执行run方法,而不创建新的执行线程。只有t.start()创建了一个单独的操作系统线程。

如果线程因未处理的异常结束,会发生什么?

如果抛出未处理的异常,线程将异常终止,其堆栈跟踪将输出到错误流,而其他线程不受影响。

常见错误和反模式

  • 调用run()而不是start()
  • 线程未及时结束(例如,未处理InterruptedException
  • 创建无条件结束的无限线程

生活中的实例

消极案例

程序员通过run()方法启动线程,以为它与main并行运行,但实际上所有操作都是顺序执行的。

优点:

  • 程序逻辑正常工作

缺点:

  • 没有并行性,错过了执行时间优化

积极案例

正确使用start()、适当处理异常、使用join()等待线程结束。

优点:

  • 实际并行性
  • 可控的结束

缺点:

  • 需要注意同步,调试可能复杂