【问题标题】:Java Threads vs PthreadsJava 线程与 Pthread
【发布时间】:2011-03-11 06:05:24
【问题描述】:

我在今天的采访中被问到这个问题。

"当我们用pthread_create()(POSIX Threads)创建线程时,线程自己启动,为什么Java中需要显式调用start(),为什么Java不启动线程的原因是什么?创建它的一个实例。”

我当时一头雾水,面试官时间紧迫,最终他无法向我解释原因。

【问题讨论】:

  • 所以你的面试官也无法解释答案? :) 呵呵

标签: java multithreading posix


【解决方案1】:

在 Java 中,不立即启动线程会导致更好的 API。您可以在线程上设置属性(守护进程、优先级),而无需在构造函数中设置所有属性。

如果线程立即启动,则需要一个构造函数,

public Thread(Runnable target, String name, ThreadGroup threadGroup, int priority, boolean daemon, ContextClassLoader contextClassLoader, long stackSize)

允许在线程启动之前设置所有这些参数。线程启动后无法设置 daemon 属性。

我猜测 POSIX API 在调用pthread_create() 时采用了一个包含所有线程属性的结构,因此立即启动线程是有意义的。

【讨论】:

  • posix API 确实采用了一个包含所有线程属性的结构。有问题的结构是 pthread_attr_t。至于哪种方法更好,我不能站在一边。这在很大程度上取决于您对什么感到满意。两者都没有任何真正的技术优势,这只是 API 的公开方式。
  • 一旦线程启动,这些参数都无法更改。 Name 肯定可以随时更改。它保存在 java 堆中,并且在本机操作系统部分中没有表示。然而,类加载器 (ccl) 在执行过程中发生了很多变化,而变化是它的主要目标。优先级也可以改变。守护进程也可以随时更改。
  • @bestsss: setDaemon() "必须在线程启动之前调用。"。
  • @Varun:在这种情况下,创建struct 实际上与创建Thread 对象相同。填充其字段在 Java 中以类似的方式完成(使用 setter 而不是直接字段访问),然后调用 pthread_create 相当于调用 start()。这两个 API 比乍一看更相似。
  • @Joachim,这是真的,守护进程只能在启动前和死亡后更改
【解决方案2】:

原因很多。但我会给你一些:

  • 线程本身可能会在返回实例之前开始执行。
  • 必须在运行线程之前正确设置上下文类加载器(查看上一点)
  • 应在启动线程之前设置优先级等额外配置
  • pthreads 使用指向已初始化结构的指针,因为 java.lang.Thread 无法在 c-tor 结束时正确初始化,请参见以上几点;直接调用原生 pthread_create 来实际执行代码是没有意义的

希望你能明白。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    相关资源
    最近更新 更多