2013-07-02 15 views
13

Jestem nowy w technologii Java. Wiem, że istnieje tylko dwa sposoby tworzenia Thread w JavieW jaki sposób wątek główny utworzony przez Javę

  • Rozszerzanie klasy Thread
  • wykonawcze Runnable interfejs

więc jest to tylko dwa sposoby tworzenia Thread. Ale kiedy rozpoczynamy nasz program z główną maszyną JVM, uruchomiliśmy jeden główny Thread. Myślę, że nawet JVM musi przestrzegać reguły tworzenia głównych elementów JVM, czy też musi rozszerzyć klasę Thread lub wdrożyć Runnable.

public class MainThreadExample { 

    public static void main(String[] args) { 

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

Najlepiej wypróbowałem mój poziom, ale nie byłem w stanie dowiedzieć się, w jaki sposób JVM stworzył ten główny obiekt. Ponieważ w całości przeszedłem przez główną klasę (sun.tool.jar) wiem, że to klasa, która jest odpowiedzialna za główny wątek. Ale po przeszukiwaniu tak wielu stron internetowych w Google nie jest w stanie go zdobyć. Więc proszę o pomoc i jeśli to możliwe, odeślij mi przykład lub link również.

P.S: Uczę się technologii Java, nie powinienem był zawracać sobie głowy tym, jak stworzyli główny i wszystko to jest rzeczą projektującą. Ale myślę, że jest to logiczne pytanie do zadawania

+1

Zgaduję, że jest to anonimowa podklasa "Thread" –

+0

Co mówi 't.getClass(). GetFullName()'? –

+0

nie ma żadnej zasady, że jeśli nie zobaczymy Runnable i Thread facetów, więc nie ma żadnego wątku, metoda zostanie wywołana przez wątek, można również uruchomić każdą nić przez odbicie, podczas gdy nie są one pustym przebiegiem() JVM tworzy wątek i wewnątrz wątku wywołuje główną metodę –

Odpowiedz

16

Instancja java.lang.Thread nie jest wątkiem; może być używany do reprezentowania wątku wykonania w JVM, ale JVM jest w stanie w ogóle tworzyć wątki bez użycia klasy Thread.

Tak dzieje się z głównym wątkiem: JVM go tworzy, a instancja java.lang.Thread jest tworzona, aby reprezentować ją później.

W JVM Hotspot istnieje kod związany z gwintowaniem w klasie Threads zdefiniowanej w src/share/vm/runtime/thread.hpp i src/share/vm/runtime/thread.cpp. Uruchomienie JVM wywołuje funkcję statyczną Threads::create_vm, która już działa w wątku skonfigurowanym przez system operacyjny. W ramach tej funkcji znajdziemy:

(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(); 

Klasa JavaThread najwyraźniej wykorzystywane do księgowości; łączy wątek systemu operacyjnego lub maszyny wirtualnej z obiektem wątku Java. Obiekt Java najwyraźniej jeszcze nie istnieje. Następnie kod idzie zainicjować różne inne rzeczy, a później jeszcze w tej samej funkcji możemy znaleźć to:

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); 

Innymi słowy, to inicjuje System, ThreadGroup i Thread klas, a następnie tworzy instancję z numeru Thread, do którego odwołuje się thread_object (wiersz 3342) i ustawia instancję Thread dla głównego .

Jeśli zastanawiasz się co create_initial_thread robi, widocznie to przydziela instancji wątku, przechowuje wskaźnik do obiektu w prywatnej eetop dziedzinie instancji przewlec JavaThread (C++), ustawia pole priorytetu wątku normalne, wywołuje Thread(ThreadGroup group,String name) konstruktor i zwraca instancję:

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 } 

Teraz to robi maszyna wirtualna Hotspot. Inne implementacje, takie jak IBM J9, Oracle JRockit lub Azul Zing, prawdopodobnie robią jednak coś podobnego.

+0

Dziękuję bardzo za odpowiedź na Joni.Ale możesz trochę wyjaśnić, jak Java wykonała tę instancję Java.lang.Thread, aby go reprezentować. Przeszedłem przez cały główny i Klasa wątków, ale jej nie zrozumiał – Arun

+0

Główny wątek i obiekt 'java.lang.Thread', który go reprezentuje, musi zostać utworzony w natywnym kodzie. Przyjrzę się źródłom OpenJDK, może uda mi się zlokalizować lokalizację. – Joni

+0

To byłaby świetna pomoc. Dziękuję bardzo za pomoc – Arun

3

Uważam, że dokładna mechanika jest specyficzna dla JVM. Specyfikacje są trochę niejasne, ale Thread Javadoc oferuje następujące możliwości:

Kiedy Java Virtual Machine uruchamia się, jest zazwyczaj pojedynczy wątek non-demona (który zazwyczaj wywołuje metodę o nazwie main jakiejś wyznaczonej klasie) .

Nie wydaje się, aby to było odwzorowane na wystąpienie klasy Thread.

+0

Kiedy mówisz "specyfikacje są trochę niejasne", do której części JLS/JVMS się odwołujesz? – Pacerier

Powiązane problemy