Java Myth 3: Atomic operations are thread-safe

Source: Internet
Author: User
Sub-operations in Java are often mentioned in thread security arguments. As defined, atomic operations are not interrupted, so they are considered thread-safe. In fact, some atomic operations are not necessarily thread-safe.

The cause of this problem is to minimize the numberCode. Synchronization compromises performance, although the loss varies with the JVM. In addition, in the modern JVM, the synchronization performance is gradually improved. However, using synchronization still has a performance cost, andProgramMembers will always try their best to improve their code efficiency, so this problem continues.

In Java, 32-bit or less-digit values are atomic. On a 32-bit hardware platform, other primitive types except the double and long types usually use 32-bit representation, while the double and long types usually use 64-bit representation. In addition, the object reference is implemented using a local pointer, which is usually 32-bit. These 32-bit operations are atomic.

These primitive types are usually represented by 32-bit or 64-bit, which introduces another myth: the size of the primitive type is ensured by the language. This is not correct. The Java language guarantees the range of the number of tables of the original type rather than the storage size in the JVM. Therefore, int type always has the same table number range. A 32-bit implementation may be used on one JVM, while a 64-bit implementation may be used on another JVM. I would like to emphasize again that:On all platforms, the number range of tables is guaranteed, and 32-bit and smaller value operations are atomic..

Under what circumstances are atomic operations not thread-safe? The main point is that they may indeed be thread-safe, but this is not guaranteed! The Java thread allows the thread to save copies of variables in its own memory zone. The thread is allowed to use a local private copy for work, instead of using the primary storage value every time to improve performance. Consider the following classes:

ClassRealtimeclock
{
 Private IntClkid;
 Public IntClockid ()
{
ReturnClkid;
}
 Public VoidSetclockid (IntID)
{
Clkid = ID;
}
//...
}

Now, one instance of realtimeclock and two threads call setclockid and clockid at the same time, and the following event sequence occurs:

T1 call setclockid (5)
T1 puts 5 into its own private working memory
T2 call setclockid (10)
T2 puts 10 into its own private working memory
T1 calls clockid, which returns 5
5 is returned from the private working memory of T1

The call to clocki should return 10 because this is set by T2, but 5 is returned because the read/write operation is performed on the private working memory rather than the primary memory. Assignment operations are atomic, but because JVM allows such actions, thread security is not certain. At the same time, JVM behavior is not guaranteed.
 
The two threads have their own private copies instead of the primary memory. If this behavior occurs, the private local variables must be consistent with the primary storage under the following two conditions:

1. Use volatile to declare Variables
2. The accessed variable is in the synchronization method or synchronization block.

If the variable is declared as volatile, it will be consistent with the primary storage during each access. This consistency is ensured by the Java language and is atomic, even a 64-bit value. (Note that many JVMs do not correctly implement the volatile keyword. You can find more information at www.domainoft.com .) In addition, if the variable is accessed in the synchronous method or synchronization block, when the lock is obtained at the entrance of the method or block and the method or block exits, the lock is released because the variable is synchronized.
Any method can ensure that clockid returns 10, that is, the correct value. If the frequency of variable access is different, your selected performance is different. If you update many variables, using volatile may be slower than using synchronization. Remember, if the variable is declared as volatile, it will be consistent with the primary storage during each access. In contrast, when using synchronization, the variables are only consistent with the primary storage when the lock is obtained and the lock is released. However, synchronization causes less code concurrency.

If you update many variables and do not want to have the loss of synchronizing each access to the primary storage, or you want to exclude concurrency for other reasons, you can consider using synchronization.

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.