From an operating system perspective, inter-thread communication is much easier than interprocess communication because the memory space of the process can be shared between threads. As a result, they can share all the content that resides on the process global data area and on the stack and heap.
The only thing that belongs to a thread is the stack of threads-------It can hold objects that belong only to threads.
The following explains the communication between threads:
1. Variables for shared processes
This is the most basic way to communicate, but be careful not to share the variables on the thread stack, because it can be destroyed by a thread at any time, and the other thread cannot access it.
Therefore, the Java compiler does not allow the use of variables on the stack to share.
Example 1:
As the following compiler will be an error,
Protectedvoid onCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview ( r.layout.activity_main); int i=0; Thread A=newthread (New Runnable () {@Overridepublic Voidrun () {//todoauto-generated method stubi++;}});}
The above automatic variable I can be seen as a process variable, but it may be destroyed by the thread that is requesting it, because it cannot be used for sharing.
Example 2:
Positive examples like handler in Android, which need to be shared in the process space.
2. TLS (Thread Local Storage)
Thread-local storage is essentially a Key-value key-value pair that stores a series of thread numbers and Looper objects.
Like Android Looper.
Public Finalclass Looper {privatestatic final String TAG = "Looper"; Sthreadlocal.get () would return null unlessyou ' ve called prepare (). Static final threadlocal<looper>sthreadlocal = new threadlocal<looper> (); private static Looper Smainlooper; Guarded by Looper.class final MessageQueue mqueue; Final Thread Mthread; Private Printer mlogging;}
The Looper has a static
Static final threadlocal<looper> sthreadlocal = newthreadlocal<looper> ();
Threadlocal is essentially a series of thread numbers and Key-value key-value pairs for Looper objects, because sthreadlocal is static, so it is shared for all threads.
The Sthreadlocal.get () is the looper that corresponds to the current thread.
Example:
Start a worker thread to do things
private static Class Worker Implementsrunnable {... Publicvoid run () { synchronized (mLock) { looper.prepare (); Mlooper= Looper.mylooper (); Mlock.notifyall (); } Looper.loop (); } Publicvoid quit () { mlooper.quit (); } }
Which Looper. Prepare () is to re-create a looper, view the Looper source, then call the
Sthreadlocal.set (New Looper (quitallowed));
That is, a key-value pair was inserted into the sthreadlocal.
Another looper has a MessageQueue that is used to store the message.
In both Looper and handler, Looper implements inter-thread communication, handler is the encapsulation of looper, and is the friendly interface of Looper, which is convenient for users to call. And handler is shared among various threads to achieve the purpose of multi-threaded communication.
3. Concurrency, synchronization, and mutual exclusion (Java)
3.1 Synchronize Keywords
This is monitor, which guarantees mutual exclusion, a piece of code cannot be accessed by two threads at the same time.
3.2 Semaphore class
The semaphore class in Java is concurrency controlled, that is, it can limit the number of threads accessing a resource (or code block). When the number of threads set is 1 o'clock, concurrency is actually degraded to mutual exclusion.
3.3 Lock Class
The lock class can also replace object notify and wait
3.4 Object Lock
Synchronized+object's notify and wait, these three together constitute the synchronization.
For example, the following procedure ensures that thread A and thread B are executed alternately.
Example:
public void onclick_start_thread_a (View v) {LOGGER.D ("onclick_start_thread_a"); Runnable r = new Runnable () {@Override public void run () {//TODO auto-generated method stub while (true) {synchronized (flag) {System.out.println ("Thread a!"); Flag.notifyall (); try {flag.wait (); } catch (Interruptedexception e) {e.printstacktrace (); } } } } }; Thread t = new Thread (r); T.start ();} Public voidonclick_start_thread_b (View v) {LOGGER.D ("onclick_start_thread_b"); Runnable r = new Runnable () {@Override public void run () {//TODO auto-generated method stub while (true) {synchronized (flag) {System.out.println ("Thread b!"); Flag.notifyall (); try {flag.wait (); } catch (Interruptedexceptione) {e.printstacktrace (); } } } } }; Thread t = new Thread (r); T.start ();}
Report:
The following is a code that uses Handler,looper
private static Class Worker implementsrunnable {privatefinal Object mLock = new Object (); Privatelooper Mlooper; /** * Createsa worker thread with the given name. The thread * thenruns a {@link android.os.Looper}. * @paramname A name for the new thread */Worker (stringname) {Threadt = new thread (NULL, this, name); T.setpriority (thread.min_priority); T.start (); Synchronized (MLock) {while (mlooper = = null) {try {mlock.wait (); } catch (Interruptedexception ex) {}}}} Publiclooper Getlooper () {returnmlooper; } publicvoid Run () {synchronized (MLock) {looper.prepare (); Mlooper= Looper.mylooper (); Mlock.notifyall (); } looper.loop (); } publicvoid Quit () {mlooper.quit (); }} package com.example.test; Import Android.app.activity;import android.graphics.bitmap;import android.os.bundle;import Android.os.Handler; Import Android.os.looper;import android.os.message;import android.view.view;import Android.widget.ProgressBar; Import Android.widget.TextView; Public Classprogresstestactivity extends Activity {privateprogressbar progress; private TextView text; Private Worker Mworker; Privateworkerhandler Mworkerhandler; Private Uihandlermuihandler; @Override public void OnCreate (bundlesavedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); Progress = (ProgressBar) Findviewbyid (R.ID.PROGRESSBAR1); Text = (TextView) Findviewbyid (R.ID.TEXTVIEW1); Mworker = new Worker ("Artworker"); Mworkerhandler = Newworkerhandler (Mworker.getlooper ()); Muihandler = Newuihandler (Looper.mylooper ()); Public voidstartprogress (view view) {Message msgobj = Mworkerhandler.obtainmessage (); Msgobj.what = 2; Mworkerhandler.sendmessage (Msgobj); }//Simulatingsomething timeconsuming Private voiddofakework () {try {thread.sleep (1000); } catch (Interruptedexception e) {e.printstacktrace (); }} private static class Worker implements runnable{private Final Object mLock = new Object (); Private Looper Mlooper; /** * Creates a worker thread with the given name. The thread then runs a * {@link android.os.Looper}. * * @param name * A name for the new thread */Worker (String name) {T Hread t = new Thread (null, this, name); T.setpriority (thread.min_priority); T.start (); Synchronized (MLock) {while (mlooper = = null) {try { Mlock.wait (); } catch (Interruptedexception ex) {}}}} public Loopergetloo Per () {return mlooper; } public void Run () {synchronized (MLock) {looper.prepare (); Mlooper = Looper.mylooper (); Mlock.notifyall (); } looper.loop (); } public void Quit () {mlooper.quit (); }} public class Uihandlerextends Handler {private Long malbumid =-1; Public Uihandler (Looperlooper) {super (Looper); } @Override public Voidhandlemessage (Message msg) {if (msg.what = = 1) {int Valu e =msg.getdata (). GetInt ("value"); Progress.setprogress (value); Messagemsgobj = Mworkerhandler.obtainmessage (); Msgobj.what = 2; Mworkerhandler.sendmessage (Msgobj); }}} public Classworkerhandler extends Handler {private int value = 0; Public Workerhandler (Looperlooper) {super (Looper); } @Override public Voidhandlemessage (Message msg) {if (Msg.what = = 2) {Dofakewo RK (); if (value = =) value = 0; Messagemsgobj = Muihandler.obtainmessage (); Msgobj.what = 1; Bundle B = new bundle (); B.putint ("value", value++); Msgobj.setdata (b); Muihandler.sendmessage (Msgobj); } } }}
Principle of inter-thread communication