Thread Base: Thread (3) basic threading operations in--java (middle)

Source: Internet
Author: User

(next to Thread base: Thread (2) basic threading operation in--java (above) ")

1-4, pay attention to the use of synchronized keywords

In the previous article, we mainly explain how the "object lock" works in threads and how to do it. When explaining the Synchronized keyword, we also mentioned the location where the Synchronized keyword can be labeled. You often see quite a few web stickers, loading the synchronized keyword into the code's method body in their code example, and then telling the reader that this operation is thread-safe. The code might look like this:

/** * 这个类的class对象进行检查。 */publicstaticsynchronizedvoiddoSomething() {}/** * 对这个类的实例化对象进行检查 */publicsynchronizedvoiddoOtherthing() {}

But in fact, whether an object is thread-safe is more important than adding the Synchronized keyword to see how this object is manipulated . In the code below, we show the Dootherthing method in two threads (so-called thread-safe method) to manipulate an object nowvalue:

 PackageTest.thread.yield;ImportOrg.apache.commons.logging.Log;ImportOrg.apache.commons.logging.LogFactory;ImportOrg.apache.log4j.BasicConfigurator;/** * Used to wait for wake-up after startup * @author Yinwenjie * * Public  class syncthread implements Runnable {    /** * Log * *    Private Static FinalLog LOGGER = Logfactory.getlog (Syncthread.class);PrivateInteger value;Private StaticInteger Nowvalue;Static{basicconfigurator.configure (); } Public Syncthread(intValue) { This. value = value; }/** * Check the instantiation object of this class * /    Private synchronized void dootherthing() {Nowvalue = This. value; Logger.info ("The value of the current Nowvalue:"+ Nowvalue); }@Override     Public void Run() {Thread CurrentThread = Thread.CurrentThread (); Long id = currentthread.getid (); This. dootherthing (); } Public Static void Main(string[] args)throwsException {Thread SyncThread1 =NewThread (NewSyncthread (Ten)); Thread syncThread2 =NewThread (NewSyncthread ( -));        Syncthread1.start ();    Syncthread2.start (); }}

In the case of debug, there may be a dirty read of the value of the static object Nowvalue:

0 [Thread-1] INFO test.thread.yield.SyncThread  - 当前NOWVALUE的值:100730 [Thread-0] INFO test.thread.yield.SyncThread  - 当前NOWVALUE的值:100

Here's why the code has a bug:

    • The SyncThread1 object and the SyncThread2 object are two different instances of the Syncthread class. The Synchronized keyword in the private synchronized void dootherthing () method actually makes a different target for the synchronization check.

    • If you want to perform a synchronous check of multiple instance objects of a class, you should check the class object for the classes synchronously. The wording should be: "Private synchronized static void Dootherthing ()"

    • Of course, in order to check the class object of this kind (syncthread), you don't even have to label the synchronized keyword on a static method, and the object lock state check of Syncthread class is individually labeled:

privatevoiddoOtherthing() {    synchronized (SyncThread.class) {        this.value;        LOGGER.info("当前NOWVALUE的值:" + NOWVALUE);    }}

Therefore, whether an object is thread-safe in addition to adding synchronized keyword, but also to see how to do the operation of this object, the method labeled synchronized keyword, the operation for an object is not necessarily thread-safe!

2. Basic threading Operations in Java

This is the thread state switch legend that has been given in the previous article, and perhaps some readers do not fully understand the switching conditions, but it's okay to start with this section we'll go into more detail about how these thread states work in Java.

This section explains notify, Notifyall, interrupt, join, and sleep, in addition to the wait, wait (time) operations that were mentioned in the previous section when explaining "object locks."

2-1, notify and Notifyall operation

In the Java JDK, the explanations for the Notify method and the Notifyall method are:

    • Notify

Wakes up a single thread, that's waiting on this object ' s monitor. If any threads was waiting on the This object, one of the them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object ' s monitor by calling one of the wait methods.

The awakened thread is not being able to proceed until the current thread relinquishes the lock on this object. The awakened thread would compete in the usual manner with any other threads that might being actively competing to Synchroniz E on the This object; For example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object .

    • Notifyall:

Wakes up all threads is waiting on this object ' s monitor. A thread waits on an object ' s monitor by calling one of the wait methods.

The awakened threads is not being able to proceed until the current thread relinquishes the lock on this object. The awakened threads would compete in the usual manner with any other threads that might being actively competing to Synchroni Ze on this object; For example, the awakened threads enjoy no reliable privilege or disadvantage in being the next thread to lock this object .

To illustrate the work of the Notify method and the Notifyall method, I will give a piece of code for these two methods and explain them in detail.

The work of 2-1-1 and notify methods
    • Parentnotifythread class:
 Packagetest.thread.notify;ImportOrg.apache.log4j.BasicConfigurator;/** * This thread is used to make notify requests * @author Yinwenjie */ Public  class parentnotifythread implements Runnable {    /** * The "key" of this object, held for each Childnotifythread object, simulates this object as an exclusive phenomenon for all Childnotifythread objects */     Public Static FinalObject Wait_chileobject =NewObject ();Static{basicconfigurator.configure (); } Public Static void Main(string[] args)throwsException {NewThread (NewParentnotifythread ()). Start (); } Public void Run() {/ * * 3 threads for independent preemption of Wait_chileobject objects, observation * */        intMaxindex =3; for(intindex =0; Index < Maxindex; index++) {Childnotifythread childnotify =NewChildnotifythread (); Thread Childnotifythread =NewThread (childnotify);        Childnotifythread.start (); }/* * Please add eclipse breakpoints here, * to ensure that the wait () method in Childnotifythread is first executed. * * in real-world situations, you can block by a Boolean (or otherwise) * You can also use the Countdownlatch class * */        synchronized(Parentnotifythread.wait_chileobject)        {ParentNotifyThread.WAIT_CHILEOBJECT.notify (); }//no specific presentation meaning;        //Just to make sure Parentnotifythread won't quit        synchronized(Parentnotifythread.class) {Try{ParentNotifyThread.class.wait (); }Catch(Interruptedexception e)            {E.printstacktrace (); }        }    }}
    • Childnotifythread class:
 Packagetest.thread.notify;ImportOrg.apache.commons.logging.Log;ImportOrg.apache.commons.logging.LogFactory;/** * Used to wait for wake-up after startup * @author Yinwenjie * * Public  class childnotifythread implements Runnable {    /** * Log * *    Private Static FinalLog LOGGER = Logfactory.getlog (Childnotifythread.class);@Override     Public void Run() {Thread CurrentThread = Thread.CurrentThread ();Longid = Currentthread.getid (); ChildNotifyThread.LOGGER.info ("Threads"+ ID +"Start successfully, ready to enter the waiting state");synchronized(Parentnotifythread.wait_chileobject) {Try{ParentNotifyThread.WAIT_CHILEOBJECT.wait (); }Catch(Interruptedexception e)            {ChildNotifyThread.LOGGER.error (E.getmessage (), E); }        }//Execute here to indicate that the thread has been awakenedChildNotifyThread.LOGGER.info ("Threads"+ ID +"Be awakened!" "); }}

In the above two pieces of code, the Parentnotifythread class is responsible for creating objects of three childnotifythread classes, each of which has an instance object of Childnotifythread class holding Parentnotifythread.wait_ Chileobject the "key" of the object and exits the exclusive state of the Parentnotifythread.wait_chileobject object through the WAIT method (but does not return the lock), as shown in:

We then unblocked the blocking state through the ParentNotifyThread.WAIT_CHILEOBJECT.notify () method in the Parentnotifythread class:

synchronized (ParentNotifyThread.WAIT_CHILEOBJECT) {    ParentNotifyThread.WAIT_CHILEOBJECT.notify();}

The above code performs as follows:

0[thread-1] INFO Test. Thread. Notify. Childnotifythread-Thread -Start successfully, ready to enter the waiting state1[thread-2] INFO Test. Thread. Notify. Childnotifythread-Thread theStart successfully, ready to enter the waiting state1[thread-3] INFO Test. Thread. Notify. Childnotifythread-Thread -Start successfully, ready to enter the waiting state87285[thread-1] INFO Test. Thread. Notify. Childnotifythread-Thread -Be awakened!

In fact, we only know that there are three instance objects of the Childnotifythread class that are waiting for the Parentnotifythread.wait_chileobject object's "lock core" idle We do not know that the ParentNotifyThread.WAIT_CHILEOBJECT.notify () method will "lock the core" of the Parentnotifythread.wait_chileobject object (exclusive) to which thread of the three threads (this decision process is done by the operating system). and we also know that the ParentNotifyThread.WAIT_CHILEOBJECT.notify () method will only wake up waiting for Parentnotifythread.wait_chileobject object "lock Core" One of the three instance objects of the Childnotifythread class (exclusive rights) .

The work of 2-1-2 and Notifyall methods

Actually understanding the work of the Notify () method, it is not difficult to understand the work of the Notifyall () method. Next, the same code as the above section, we will parentnotifythread the ParentNotifyThread.WAIT_CHILEOBJECT.notify () method in the class, Replace with the ParentNotifyThread.WAIT_CHILEOBJECT.notifyAll () method. As shown in the following code snippet:

synchronized (ParentNotifyThread.WAIT_CHILEOBJECT) {    ParentNotifyThread.WAIT_CHILEOBJECT.notifyAll();}

Then we observe the result of the code execution:

0[thread-2] INFO Test. Thread. Notify. Childnotifythread-Thread theStart successfully, ready to enter the waiting state0[thread-1] INFO Test. Thread. Notify. Childnotifythread-Thread -Start successfully, ready to enter the waiting state0[thread-3] INFO Test. Thread. Notify. Childnotifythread-Thread -Start successfully, ready to enter the waiting state26834[thread-3] INFO Test. Thread. Notify. Childnotifythread-Thread -Be awakened!30108[thread-1] INFO Test. Thread. Notify. Childnotifythread-Thread -Be awakened!35368[thread-2] INFO Test. Thread. Notify. Childnotifythread-Thread theBe awakened!

We see the fact that three threads in the system that are waiting for the "lock Core" (exclusive) of the Arentnotifythread.wait_chileobject object lock are woken up sequentially (with exclusive rights in turn).

(next)

Thread Base: Thread (3) basic threading operations in--java (middle)

Related Article

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.