Thread basics: thread (3) -- basic thread operations in JAVA (medium)

Source: Internet
Author: User

Thread basics: thread (3) -- basic thread operations in JAVA (medium)
1-4. Pay attention to the use of the synchronized keyword.

In the previous article, we mainly explained the working principle and operation method of the "Object lock" in the thread. When explaining the synchronized keyword, we also mentioned the location where the synchronized keyword can be labeled. We often see a considerable number of Web posts. In their code examples, we load the synchronized keyword to the method body of the Code, and then tell the reader that this operation is thread-safe. The code may be as follows:

/*** Check the class object of this class. */Public static synchronized void doSomething () {}/ *** checks the instantiated object of this class */public synchronized void doOtherthing (){}

But in fact, in addition to adding the synchronized keyword, whether an object is thread-safe also depends on how to operate the object.. In the following code, we show the doOtherthing method (so-called thread security method) in two threads to operate an object NOWVALUE:

Package test. thread. yield; import org. apache. commons. logging. log; import org. apache. commons. logging. logFactory; import org. apache. log4j. basicaggregator;/*** is used to wait for wake-up after startup * @ author yinwenjie */public class SyncThread implements Runnable {/*** Log */private static final Log LOGGER = LogFactory. getLog (SyncThread. class); private Integer value; private static Integer NOWVALUE; static {basicaggregator. configure ();} public SyncThread (int value) {this. value = value;}/*** check the instantiated object of this class */private synchronized void doOtherthing () {NOWVALUE = this. value; LOGGER.info ("Current NOWVALUE value:" + NOWVALUE) ;}@ Override public void run () {Thread currentThread = Thread. currentThread (); Long id = currentThread. getId (); this. doOtherthing ();} public static void main (String [] args) throws Exception {Thread syncThread1 = new Thread (new SyncThread (10 )); thread syncThread2 = new Thread (new SyncThread (100); syncThread1.start (); syncThread2.start ();}}

From the Debug perspective, dirty reads may occur to the value of the static object NOWVALUE:

0 [Thread-1] INFO test. thread. yield. syncThread-current NOWVALUE value: 100730 [Thread-0] INFO test. thread. yield. syncThread-current NOWVALUE: 100

The following are the causes of bugs in the Code:

The syncThread1 object and syncThread2 object are two different instances of the SyncThread class. The synchronized keyword in the "private synchronized void doOtherthing ()" method actually has different synchronization check targets.

If you want to perform a synchronization check on multiple instance objects of the class, you should perform a synchronization check on the class objects of the class. The statement should be: "private synchronized static void doOtherthing ()"

Of course, to perform a synchronization check on the class objects of this class (SyncThread), you do not even need to mark the synchronized keyword on the static method, but the object lock status check of the class with the SyncThread annotation separately:

Private void doOtherthing () {synchronized (SyncThread. class) {NOWVALUE = this. value; LOGGER.info ("Current NOWVALUE value:" + NOWVALUE );}}

Therefore, in addition to adding the synchronized keyword, whether an object is thread-safe also depends on how to operate the object. In the method marked with the synchronized keyword, operations on an object are not necessarily thread-Safe!

2. Basic thread operations in JAVA

This is an example of thread status switching. Some readers may not fully understand the switching conditions, it doesn't matter from this chapter we will detail how to operate these thread states in JAVA. <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> Examples/zy/gmcmRxdW87tcTKsbry0tG + examples/ehozwvcD4NCjxoMiBpZD0 = "2-1policy and policyall operations"> 2-1, policy, and policyall operations

In java jdk, the notify and notifyAll methods are interpreted as follows:

Notify:

Wakes up a single thread that is waiting on this object's monitor. if any threads are waiting on this object, one of 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 will not be able to proceed until the current thread relinquishes the lock on this object. the awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.

Policyall:

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

The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object. the awakened threads will compete in the usual manner with any other threads that might be actively competing to synchronize 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 working phenomena of the notify and notifyAll methods, I will provide a piece of code for the two methods and explain them in detail.

2-1-1. parentpolicythread class:
Package test. thread. notify; import org. apache. log4j. basicaggregator;/*** this thread is used to send a y request * @ author yinwenjie */public class parentpolicythread implements Runnable {/*** the "key" of this object ", it is held by each ChildNotifyThread Object. * simulate that this Object is exclusive to all ChildNotifyThread objects */public static final Object WAIT_CHILEOBJECT = new Object (); static {BasicConfigurator. configure ();} public static void main (String [] args) throws Exception {new Thread (new parentpolicythread ()). start ();} public void run () {/** 3 threads that are used to independently preemptible the WAIT_CHILEOBJECT object. Observe the situation **/int maxIndex = 3; for (int index = 0; index <maxIndex; index ++) {ChildNotifyThread childNotify = new ChildNotifyThread (); Thread childNotifyThread = new Thread (childNotify); childNotifyThread. start ();}/** Add the eclipse breakpoint here, * to ensure that the wait () method in ChildNotifyThread is executed first. ** In a real environment, you can use a Boolean (or other method) to determine blocking * or use the CountDownLatch class **/synchronized (parentpolicythread. WAIT_CHILEOBJECT) {parentpolicythread. WAIT_CHILEOBJECT.notify ();} // no specific demonstration meaning; // only to ensure that parentpolicythread does not exit synchronized (parentpolicythread. class) {try {parentpolicythread. class. wait ();} catch (InterruptedException e) {e. printStackTrace ();}}}}
ChildNotifyThread class:
Package test. thread. notify; import org. apache. commons. logging. log; import org. apache. commons. logging. logFactory;/*** is used to wait for wake-up * @ author yinwenjie */public class ChildNotifyThread implements Runnable {/*** Log */private static final Log LOGGER = LogFactory after startup. getLog (childpolicythread. class); @ Override public void run () {Thread currentThread = Thread. currentThread (); long id = currentThread. getId () ; ChildNotifyThread.LOGGER.info ("Thread" + id + "started successfully, ready to enter the waiting state"); synchronized (parentpolicythread. WAIT_CHILEOBJECT) {try {parentpolicythread. WAIT_CHILEOBJECT.wait ();} catch (InterruptedException e) {childpolicythread. LOGGER. error (e. getMessage (), e) ;}// the thread is awakened by ChildNotifyThread.LOGGER.info ("Thread" + id +! ");}}

In the above two sections of code, the parentpolicythread class is responsible for creating three ChildNotifyThread class objects. Each ChildNotifyThread class instance object holds the "key" of the parentpolicythread. WAIT_CHILEOBJECT object ",And exit the exclusive state of the parentpolicythread. WAIT_CHILEOBJECT object through the wait method (but the lock is not returned), As shown in:

Then, we use the parentpolicythread. wait_chileobject.y y () method in the parentpolicythread class to remove the blocking status:

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

The preceding code is executed as follows:

0 [Thread-1] INFO test. thread. policy. childNotifyThread-Thread 14 is started successfully. Prepare to enter the waiting state 1 [Thread-2] INFO test. thread. policy. childNotifyThread-Thread 15 is started successfully and is ready to enter the waiting state 1 [Thread-3] INFO test. thread. policy. childNotifyThread-Thread 16 is started successfully and is ready to enter the waiting state 87285 [Thread-1] INFO test. thread. policy. childNotifyThread-thread 14 is awakened!

Actually,We only know that there are three childpolicythread class instance objects in the "Lock Core" waiting for parentpolicythread. WAIT_CHILEOBJECT object is idleWe do not know parentpolicythread. the wait_chileobject.policy () method sets parentpolicythread. the "Lock Core" (exclusive permission) of the WAIT_CHILEOBJECT object is assigned to which thread of the three threads (this decision process is completed by the operating system ).We also know that the parentpolicythread. wait_chileobject.policy () method will only wake up one of the three childpolicythread class instance objects waiting for parentpolicythread. WAIT_CHILEOBJECT "Lock Core" (exclusive).

2-1-2. How does the policyall method work?

In fact, it is not difficult to understand the working situation of the policyall () method after understanding the working situation of the policy () method. Next, we will replace the parentpolicythread. wait_chileobject.y y () method in the parentpolicythread class with the parentpolicythread. wait_chileobject.policyall () method. The following code snippet is shown:

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

Then observe the Code Execution result:

0 [Thread-2] INFO test. thread. policy. childNotifyThread-Thread 15 is started successfully. Prepare to enter the waiting state 0 [Thread-1] INFO test. thread. policy. childNotifyThread-Thread 14 is started successfully. Prepare to enter the waiting state 0 [Thread-3] INFO test. thread. policy. childNotifyThread-Thread 16 is started successfully and is ready to enter the waiting state 26834 [Thread-3] INFO test. thread. policy. childNotifyThread-thread 16 is awakened! 30108 [Thread-1] INFO test. thread. Every y. ChildNotifyThread-Thread 14 is awakened! 35368 [Thread-2] INFO test. thread. Every y. ChildNotifyThread-Thread 15 is awakened!

We see the fact that:In the system, the three threads waiting for the "Lock Core" (exclusive permission) of the arentpolicythread. WAIT_CHILEOBJECT object lock are awakened in sequence (with exclusive permission in turn).

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.