One: The origin of processes and threads
Process is the product of the development process of computer science and technology.
The earliest computers were invented to solve mathematical calculations. Every solution to a problem, it is necessary to play paper tape, that is, Dot.
Later, it was found that the commands could be set up in batches, which were read by the computer and executed in one step.
In the use of the process, there is a problem, if you want to do I/O operations, is very time-consuming, this time the CPU is idle, which is a huge waste of computer resources.
So, people invented the process of this thing. Each program is a process that is managed by the operating system, and when a complex time-consuming operation is performed, the CPU can schedule the processing of other processes, thereby improving overall performance.
Purpose of the thread:
When the CPU is scheduling a process, the process is doing network operations, this time, if the user clicks a button, is unable to respond in a timely manner, the experience is very bad. As a result, there are----threads in the dispatch unit that is more "small" than the process.
I put the action with the response in a thread, put the time-consuming operation on the other thread, the user can see the interface quick Response, no delay effect.
This is also the programming paradigm for mainstream operating systems such as Anroid:
The main thread that binds the UI action to the other tasks that are handled by the worker thread. It is mainly a time-consuming task.
Second: Thread start-up process
Creating and starting a new thread, no matter how many layers of encapsulation, is ultimately intended to be done by the API provided by the operating system.
The following is from Java thread, layer analysis, until the end of Linux pthread.
Thread source code is located at:
Libcore\libdvm\src\main\java\java\lang\thread.java
public class Thread implements Runnable {
Visible thread is the implementation of a runnable interface.
Public interface Runnable { /** * Starts executing the active part of the class ' Code. This method was * Called when a thread was started that had been created with a class which * Implements {@code Runn Able}. * /public void run ();
Runnable Nothing, it's the run function.
So the root of the thread is to create a new thread that runs the Run method.
Let's look at the process of creating threads.
Public Thread () { create (null, NULL, NULL, 0); } Public Thread (Runnable Runnable) { create (null, Runnable, NULL, 0); }
As shown above, the method of using thread in common applications is
A. Define a new thread subclass to implement the Run method.
B. Pass the run directly to thread as a parameter.
Next we look at the Create method:
Private voidCreate (Threadgroup group, Runnable Runnable, String threadname,LongstackSize) {Thread CurrentThread=Thread.CurrentThread (); if(Group = =NULL) {Group=Currentthread.getthreadgroup (); } if(group.isdestroyed ()) {Throw NewIllegalthreadstateexception ("Group already destroyed"); } This. Group =Group; synchronized(Thread.class) {ID= ++Thread.count; } if(ThreadName = =NULL) { This. Name = "Thread-" +ID; } Else { This. Name =ThreadName; } This. target =runnable; This. stackSize =stackSize; This. Priority =currentthread.getpriority (); This. Contextclassloader =Currentthread.contextclassloader; //Transfer over Inheritablethreadlocals. if(Currentthread.inheritablevalues! =NULL) {inheritablevalues=Newthreadlocal.values (currentthread.inheritablevalues); } //add ourselves to our threadgroup of choice This. Group.addthread ( This); }
Public Static Thread CurrentThread () { return vmthread.currentthread (); }
Vmthread source code is located at:
The CurrentThread of Vmthread is a native method whose JNI implementation is Android/dalvik/vm/native/java_lang_vmthread.cpp
Static void Dalvik_java_lang_vmthread_currentthread (const u4* args, jvalue* pResult) { Unused_parameter (args); Return_ptr (Dvmthreadself (),threadobj);}
Here's a dvmthreadself () method:
thread* dvmthreadself () { return (thread*) pthread_getspecific (gdvm.pthreadkeyself);}
This is an index that is stored in key pthreadkeyself.
/* */ Object* threadobj;
Threadobj is associated with the Android thread object.
Then analyze the code above, if the new thread is not assigned to the group then the group will be specified as the current thread in the group, and then set the new thread name,priority and so on. Finally, the new thread is added to the group by calling the Addthread method of Threadgroup:
/** * Called by the Thread constructor. */ final void addthread (thread thread) throws illegalthreadstateexception { synchronized (threadrefs) { if (isdestroyed) { throw new Illegalthreadstateexception (); } threadrefs.add ( new weakreference<thread>
Inside the threadrefs is a reference to each thread that the group holds.
With the above code analysis, the thread construction method simply sets some thread properties and does not create a real thread.
Thread the newly created threads:
Public synchronized void start () { checknotstarted (); true ; Vmthread.create (this, stackSize); }
The Start method of the Android Thread is simple, just the native method of the transpose Vmthread create, whose JNI implementation is Android/dalvik/vm/native/java_lang_vmthread.cpp The Dalvik_java_lang_vmthread_create method:
Static void Dalvik_java_lang_vmthread_create (const u4* args, jvalue* pResult) { Object* threadobj = (object* ) args[0]; = Get_arg_long (args, 1); /* * /Dvmcreateinterpthread (Threadobj, (int) stackSize); Return_void ();}
The Dvmcreateinterpthread function is long, but it does the most important thing:
BOOL Dvmcreateinterpthread (object* threadobj, int reqstacksize)
{
thread* self = dvmthreadself ();
thread* Newthread = Allocthread (stackSize);
Newthread->threadobj = Threadobj;
object* vmthreadobj = Dvmallocobject (Gdvm.classjavalangvmthread, Alloc_default);
Dvmsetfieldint (Vmthreadobj, Gdvm.offjavalangvmthread_vmdata, (U4) newthread);
Dvmsetfieldobject (Threadobj, Gdvm.offjavalangthread_vmthread, vmthreadobj);
pthread_t Threadhandle;
int cc = Pthread_create (&threadhandle, &threadattr, Interpthreadstart, Newthread);
/*
* Tell the new thread to start.
*
* We must hold the thread list lock before messing with another thread.
* In the general case we would also need to verify that Newthread was
* Still in the "thread list, but" the thread has not started
* Executing user code and therefore have not had a chance to exit.
*
* We Move it to vmwait, and it then shifts itself to RUNNING, which
* Comes with a suspend-pending check.
*/
Dvmlockthreadlist (self);
ASSERT (Newthread->status = = thread_starting);
Newthread->status = thread_vmwait;
Pthread_cond_broadcast (&gdvm.threadstartcond);
Dvmunlockthreadlist ();
}
/*
* Alloc and initialize a Thread struct.
*
* Does not create no objects, just stuff on the system (malloc) heap.
*/
static thread* allocthread (int interpstacksize)
{
thread* thread;
Thread = (thread*) calloc (1, sizeof (Thread));
Thread->status = thread_initializing;
}
First, a newthread Dalvik thread is created through Allocthread, and some properties are created. Set its member variable threadobj incoming Android Thread threadobj.
Creates a Vmthread object with the Vmthreadobj name.
Dvmsetfieldint (Vmthreadobj, Gdvm.offjavalangvmthread_vmdata, (U4) newthread); Dvmsetfieldobject (Threadobj, Gdvm.offjavalangthread_vmthread, vmthreadobj);
Set the Vmthreadobj Vm_data method to Newthread.
Then set the Android Thread vmthread variable to vmthreadobj.
With this vmthreadobj, the Android thread is associated with the Dalvik thread.
Then there is
int cc = pthread_create (&threadhandle, &threadattr, Interpthreadstart, Newthread);
Yes, this is the API interface for the Linux operating system to create new threads!
Next we analyze Interpthreadstart, which is the entry that runs on the new thread.
/** pthread entry function for threads started from interpreted code.*/Static void* Interpthreadstart (void*Arg) {Thread* Self = (thread*) Arg; std::string ThreadName (Dvmgetthreadname (self)); SetThreadName (Threadname.c_str ()); /** Finish initializing the Thread struct. */dvmlockthreadlist (self); Preparethread (self); while(Self->status! =thread_vmwait) pthread_cond_wait (&gdvm.threadstartcond, &Gdvm.threadlistlock); Dvmunlockthreadlist (); /** ADD a JNI context. */ Self->jnienv =dvmcreatejnienv (self); /** Change of our state so the GC would wait for us from now on . If a GC is * in progress the suspend us. */dvmchangestatus (self, thread_running); /** Execute The "Run" method. * * At the "Our stack are empty, so somebody who comes looking for * stacks traces right now won ' t has much t o Look at. This is normal. */Method* Run = self->threadobj->clazz->Vtable[gdvm.voffjavalangthread_run]; Jvalue unused; ALOGV ("Threadid=%d:calling Run ()", self->threadId); assert(strcmp (Run->name, "run") = = 0); Dvmcallmethod (self, run, self->threadobj, &unused); ALOGV ("Threadid=%d:exiting", self->threadId); /** Remove the thread from the various lists, report it death, and free * its resources. */Dvmdetachcurrentthread (); returnNULL;}/** Finish Initialization of a Thread struct. * This must is called while executing in the new thread, but before the * thread is added to the thread list. * * Note:the Threadlistlock must is held by the caller (needed for * ASSIGNTHREADID ()). */StaticBOOL Preparethread (thread*thread) {Assignthreadid (thread); Thread->handle =pthread_self (); Thread->systemtid =Dvmgetsysthreadid (); Setthreadself (thread); return true;}/** Explore our sense of self . Stuffs the thread pointer into TLS. */Static voidSetthreadself (thread*thread) { intcc; CC=pthread_setspecific (gdvm.pthreadkeyself, thread); }
First get name from Android thread, and then set some properties of the thread through Preparethread. and call the Setthreadself method, put the Dalvik thread into TLS.
Then execute the Android thread's Run method.
Public void run () { ifnull) { target.run (); } }
At this point, through the interface provided by the operating system, thread inside the Run method, in the new thread to run up!
This article refers to:
1. Deep understanding of the Android kernel design idea Lincosen
2. Anatomy of the Android kernel
3. Roche http://www.cppblog.com/kesalin/archive/2014/07/11/android_thread_impl.html
Android process/thread management (ii)----myths about threading