Principle of inter-thread communication

Source: Internet
Author: User
Tags semaphore

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.