线程相关问题

多线程知识点

yield方法可以实现那些功能?

在回答这个问题前必须先提一下yield方法的作用———暂停当前正在执行的线程对象,把CPU调度时间让出来重新分配(仍可能在结束后被调度)。
yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield的目的是让相同优先级的线程之间能适当的轮转执行。

应用场景

  • 当前线程对CPU资源的依赖不是那么大时,可以通过该方法将CPU资源让渡给其他线程。
    如,在守护进程的设计上。

开启线程有哪些因素约束?

增加更多的资源消耗

  • 每开启一个线程都需要在内存中维持一个线程本地栈,以存储每个线程中运行过程中的数据。并且,该栈的大小并不小。
  • 同时线程的运行非常依赖CPU的调度,过多的线程抢占CPU调度时间会导致计算机的响应时间下降。
  • 子问题:创建一个线程需要多少内存空间?

上下文切换的开销

线程是由CPU进行调度的,CPU的一个时间片内只执行一个线程上下文内的线程,当CPU由执行线程A切换到执行线程B的过程中会发生一些列的操作,这些操作主要有”保存线程A的执行现场“然后”载入线程B的执行现场”,这个过程称之为“上下文切换(context switch)”,这个上下文切换过程并不廉价,如果没有必要,应该尽量减少上下文切换的发生。

设计更复杂

多线程程序往往比单线程程序设计会更加复杂(尽管有些单线程处理程序可能比多线程程序要复杂),而且错误很难重现(因为线程调度的无序性,某些bug的出现依赖于某种特定的线程执行时序)。


JVM中最多支持开多少个线程

  • 对于特定的虚拟机,都会有自己的运行时参数。(最大线程数)一定程度上由操作系统决定的。
  • 绝对理论上的最大线程数是进程的用户地址空间除以线程栈的大小(现实中,如果内存全部给线程栈使用,就不会有能运行的程序了)。
  • 设置JVM的启动参数-xss可以全局控制每个线程栈的大小,也可以在线程创建后设置所要创建线程的线程栈的大小。
    相关参数:stackSize