15

私は Java テクノロジを初めて使用します。ThreadJavaで作成する方法は2つしかないことを知っています

  • スレッドクラスの拡張
  • 実行可能なインターフェイスの実装

したがって、これは を作成する 2 つの方法にすぎませんThread。しかし、プログラムを main で開始すると、JVM が 1 つの main を開始しましThreadた。JVMでさえ、メインスレッドを作成するための主な手段を作成するためのルールに従う必要があると思いますJVMは、ThreadThreadクラスを拡張するか、実装する必要がありますRunnable

public class MainThreadExample {

    public static void main(String[] args) {

        Thread t=Thread.currentThread();            
        System.out.println(t.getName());            
    }
}

私は自分のレベルで最善を尽くしましたが、JVM がこのメイン オブジェクトをどのように作成したかを知ることができませんでした。メイン クラス ( sun.tool.jar) を完全に通過したので、これがメイン スレッドを担当するクラスであることがわかりました。しかし、Google で非常に多くの Web ページを検索した後、それを取得できませんでした。助けてください。可能であれば、例またはリンクも参照してください。

PS: 私は Java テクノロジを学習しています。しかし、私はそれを尋ねるのが論理的な質問だと思います

4

2 に答える 2

19

のインスタンスはjava.lang.Threadスレッドではありません。JVM で実行のスレッドを表すために使用できますが、JVM は、Threadクラスをまったく使用せずにスレッドを完全に作成できます。

これがメイン スレッドで発生することです。JVM がメイン スレッドを作成し、java.lang.Thread後でそれを表すために のインスタンスが作成されます。

Hotspot JVM では、 および で定義されたクラスにスレッド関連のコードが多数ありThreadsます。JVM の起動は、オペレーティング システムによって設定されたスレッドで既に実行されている静的関数を呼び出します。その関数内で次のことがわかります。src/share/vm/runtime/thread.hppsrc/share/vm/runtime/thread.cppThreads::create_vm

(src/share/vm/runtime/thread.cpp)
3191   // Attach the main thread to this os thread
3192   JavaThread* main_thread = new JavaThread();
3193   main_thread->set_thread_state(_thread_in_vm);
3194   // must do this before set_active_handles and initialize_thread_local_storage
3195   // Note: on solaris initialize_thread_local_storage() will (indirectly)
3196   // change the stack size recorded here to one based on the java thread
3197   // stacksize. This adjusted size is what is used to figure the placement
3198   // of the guard pages.
3199   main_thread->record_stack_base_and_size();
3200   main_thread->initialize_thread_local_storage();

クラスはJavaThread簿記に使用されているようです。OS または VM スレッドを Java Thread オブジェクトに関連付けます。Java オブジェクトはまだ存在しないようです。その後、コードは他のさまざまなものを初期化し、後で同じ関数内で次のことを見つけます。

3335     // Initialize java_lang.System (needed before creating the thread)
3336     if (InitializeJavaLangSystem) {
3337       initialize_class(vmSymbols::java_lang_System(), CHECK_0);
3338       initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0);
3339       Handle thread_group = create_initial_thread_group(CHECK_0);
3340       Universe::set_main_thread_group(thread_group());
3341       initialize_class(vmSymbols::java_lang_Thread(), CHECK_0);
3342       oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0);
3343       main_thread->set_threadObj(thread_object);
3344       // Set thread status to running since main thread has
3345       // been started and running.
3346       java_lang_Thread::set_thread_status(thread_object,
3347                                           java_lang_Thread::RUNNABLE);

つまり、SystemThreadGroup、およびThreadクラスを初期化してから、Thread参照先のインスタンスを作成しthread_object(3342 行目)、そのThreadインスタンスを main に設定しますJavaThread

が何をするのか疑問に思っているならcreate_initial_thread、どうやら Thread インスタンスを割り当て、JavaThread(C++) オブジェクトへのポインタをeetopThread インスタンスのプライベート フィールドに格納し、スレッド優先度フィールドを通常に設定し、Thread(ThreadGroup group,String name)コンストラクタを呼び出し、インスタンスを返します。

 967 // Creates the initial Thread
 968 static oop create_initial_thread(Handle thread_group, JavaThread* thread, TRAPS) {
 969   klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_     NULL);
 970   instanceKlassHandle klass (THREAD, k);
 971   instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
 972 
 973   java_lang_Thread::set_thread(thread_oop(), thread);
 974   java_lang_Thread::set_priority(thread_oop(), NormPriority);
 975   thread->set_threadObj(thread_oop());
 976 
 977   Handle string = java_lang_String::create_from_str("main", CHECK_NULL);
 978 
 979   JavaValue result(T_VOID);
 980   JavaCalls::call_special(&result, thread_oop,
 981                                    klass,
 982                                    vmSymbols::object_initializer_name(),
 983                                    vmSymbols::threadgroup_string_void_signature(),
 984                                    thread_group,
 985                                    string,
 986                                    CHECK_NULL);
 987   return thread_oop();
 988 }

これが Hotspot VM の機能です。ただし、IBM J9、Oracle JRockit、または Azul Zing などの他の実装は、おそらく同様のことを行います。

于 2013-07-02T18:26:28.687 に答える
3

正確なメカニズムは JVM 固有のものだと思います。仕様は少しあいまいですが、ThreadJavadocは次を提供します。

Java 仮想マシンが起動すると、通常、単一の非デーモン スレッド (通常、main指定されたクラスの名前付きメソッドを呼び出します) が存在します。

これがクラスのインスタンスにどのようにマップされるかはThread指定されていないようです。

于 2013-07-02T18:28:07.513 に答える