public class JoinTest {

public static void mainString[] args throws InterruptedException { ThreadTest tt=new ThreadTest; tt.start; synchronized tt { tt.wait; } System.out.println"主线程继续。。。。";


class ThreadTest extends Thread {

public void run { forint i=0;i<5;i++{ try { Thread.sleep1000; System.out.println"i="+i; } catch InterruptedException e { e.printStackTrace; } }





过程大致是这样的:Thread.start -> start0 -> … -> createJavaCreate -> pthread_create => threadStart => attachThread -> 执行Thread的run -> detachThread “这个方法最后会调用Object.notifyAll”。


void createJavaThreadObject *jThread, long long stack_size { Thread *self = threadSelf; ExecEnv *ee = sysMallocsizeofExecEnv; Thread *thread = sysMallocsizeofThread; memsetee, 0, sizeofExecEnv; memsetthread, 0, sizeofThread; thread->ee = ee; ee->thread = jThread; ee->stack_size = stack_size; if!classlibCreateJavaThreadthread, jThread { sysFreethread; sysFreeee; return; } disableSuspendself; ifpthread_create&thread->tid, &attributes, threadStart, thread { classlibMarkThreadTerminatedjThread; sysFreeee; enableSuspendself; signalExceptionjava_lang_OutOfMemoryError, "cant create thread"; return; } pthread_mutex_lock&lock; /* Wait for thread to start */ whileclasslibGetThreadStatethread == CREATING pthread_cond_wait&cv, &lock; pthread_mutex_unlock&lock; enableSuspendself;
} .... void *threadStartvoid *arg { Thread *thread = Thread *arg; Object *jThread = thread->ee->thread; /* Parent thread created thread with suspension disabled. This is inherited so we need to enable */ enableSuspendthread; /* Complete initialisation of the thread structure, create the thread stack and add the thread to the thread list */ initThreadthread, INST_DATAjThread, int, daemon_offset, &thread; /* Add thread to thread ID map hash table. */ addThreadToHashthread; /* Set state to running and notify creating thread */ signalThreadRunningthread; /* Execute the threads run method */ executeMethodjThread, CLASS_CBjThread->class->method_table[run_mtbl_idx]; /* Run has completed. Detach the thread from the VM and exit */ detachThreadthread; TRACE"Thread %p id: %d exited
", thread, thread->id; return NULL;
} void *detachThreadThread *thread { Object *keep_alive; ExecEnv *ee = thread->ee; Object *java_thread = ee->thread; Object *group = INST_DATAjava_thread, Object*, group_offset; /* If theres an exception pending, it is uncaught */ ifexceptionOccurred0ee uncaughtException; /* Dont do anything if this is the main thread */ ifthread->prev == NULL return NULL; /* remove thread from thread group */ executeMethodgroup, CLASS_CBgroup->class-> method_table[rmveThrd_mtbl_idx], java_thread; /* Remove thread from the ID map hash table */ deleteThreadFromHashthread; objectLockjava_thread; /* Mark the thread as terminated. This state is used in determining if the thread is alive and so must be done before notifying joining threads. The VM thread structure is tied to a Java-level object see comment below. The keep_alive is an object which must be kept alive to prevent the structure from being freed while we are still accessing it */ keep_alive = classlibMarkThreadTerminatedjava_thread; /* Notify any threads waiting on the thread object - these are joining this thread 这里调用objectNotifyAll */ objectNotifyAlljava_thread; objectUnlockjava_thread; /* Threads about to die, so no need to enable suspend afterwards. */ disableSuspendthread; /* Grab global lock, and update thread structures protected by it thread list, thread ID and number of daemon threads */ pthread_mutex_lock&lock; /* It is safe to free the threads ExecEnv and stack now as these are only used within the thread. It is _not_ safe to free the native thread structure as another thread may be concurrently accessing it. However, they must have a reference to the java level thread -- therefore, it is safe to free during GC when the thread is determined to be no longer reachable. */ sysFreeee->stack; sysFreeee; /* If no more daemon threads notify the main thread which may be waiting to exit VM. Note, this is not protected by lock, but main thread checks again */ ifnon_daemon_thrds == 0 { /* No need to bother with disabling suspension around lock, as were no longer on thread list */ pthread_mutex_lock&exit_lock; pthread_cond_signal&exit_cv; pthread_mutex_unlock&exit_lock; } /* Finally, clear the thread local data */ setThreadSelfNULL; TRACE"Thread %p id: %d detached from VM
", thread, thread->id; return keep_alive;
} .... 

As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.


电子邮件地址不会被公开。 必填项已用*标注