Java Theory and Practice: the popular Atom

Source: Internet
Author: User
Tags data structures mutex

15 years ago, multiprocessor systems were highly specialized and cost hundreds of thousands of dollars (most with two to four processors). Multiprocessor systems are now cheap and numerous, with multiprocessing support built into almost every major microprocessor, many of which support dozens of or hundreds of processors.

To use the capabilities of multiprocessor systems, it is often necessary to construct applications using multithreading. But as anyone writing concurrent applications can tell you, it's not enough to get good hardware utilization, just simply splitting the work across multiple threads, and making sure that the threads do work most of the time rather than waiting for more work, or waiting to lock up shared data structures.

Problem: coordination between threads

If there is no need for coordination between threads, few tasks can really be parallel. As an example of a thread pool, the tasks performed are usually independent of each other. If the thread pool takes advantage of public work queues, the process of removing elements from the work queue or adding elements to the task force must be thread-safe, and this means reconciling access to the link pointer between the right, tail, or node. It is this coordination that leads to all the problems.

Standard Method: Lock

In the Java language, the traditional way to reconcile access to shared fields is to use synchronization to ensure that all access to shared fields is complete, with the appropriate locks. By synchronizing, you can determine that all threads that have a lock that protects a given set of variables will have exclusive access to those variables, and that changes to those variables will be visible when other threads acquire the lock later. The disadvantage is that if locking is too competitive (threads often require the lock when other threads have locks), it can damage throughput because competing synchronizations are expensive. (Public Service Announcement: for modern JVMs, no competitive sync is now very cheap.)

Another problem with locking algorithms is that if a thread with a lock is delayed (because of a page fault, schedule delay, or other unexpected delay), the thread that is not required to obtain the lock can continue to run.

You can also use variable variables to store shared variables at a lower cost than synchronization, but they have limitations. Although you can guarantee that other variables can immediately see writes to variable variables, you cannot render the read-modify-write order of atomic operations, which means (for example) that mutable variables cannot be used to reliably implement mutexes (mutex locks) or counters.

Using locks to implement counters and mutexes

If you develop a thread-safe counter class, this exposes the Get (), increment (), and decrement () operations. Listing 1 shows an example of how to use Locking (synchronization) to implement this class. Note that all methods, even the need to synchronize get (), make the Class A thread-safe class, so that no update information is lost and all threads see the latest value of the counter.

Listing 1. Counter class for synchronization

public class SynchronizedCounter {
   private int value;
   public synchronized int getValue() { return value; }
   public synchronized int increment() { return ++value; }
   public synchronized int decrement() { return --value; }
}

The increment () and decrement () operations are read-modify-write operations of atoms, and for security implementation counters, you must use the current value, add a value to it, or write out a new value, all of which are considered an operation and cannot be interrupted by other threads. Otherwise, if two threads try to execute the addition at the same time, the unfortunate crossover of the operation will cause the counter to be implemented only once, rather than being implemented two times. (Note that this operation cannot be reliably done by making the value instance variable variable.) )

Many concurrent algorithms display a read-modify-write combination of atoms. The code in Listing 2 implements a simple mutex, and the acquire () method is also an atomic read-modify-write operation. To obtain a mutex, you must ensure that no one else has the mutex (Curowner = Thread.CurrentThread ()), and then record the fact that you have the mutex (Curowner = Thread.CurrentThread ()), all of which make it His thread could not appear in the middle and modify the Curowner field.

Listing 2. Mutually exclusive classes that are synchronized

public class SynchronizedMutex {
   private Thread curOwner = null;
   public synchronized void acquire() throws InterruptedException {
     if (Thread.interrupted()) throw new InterruptedException ();
     while (curOwner != null)
       wait();
     curOwner = Thread.currentThread();
   }
   public synchronized void release() {
     if (curOwner == Thread.currentThread()) {
       curOwner = null;
       notify();
     } else
       throw new IllegalStateException("not owner of mutex");
   }
}

The counter class in Listing 1 works reliably, and can be performed well when the competition is small or competitive. However, when the competition is fierce, this will greatly impair performance, because the JVM has spent more time dispatching threads, managing competition and waiting for thread queues, while the actual work, such as increasing the number of counters, is very small. You can recall the figure in last month's column, which shows how throughput will drop dramatically once multiple threads compete with a built-in monitor for synchronization. While this column shows how the new Reentrantlock class can be more scalable to replace synchronization, there are better solutions for some problems.

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.