Java Multithreading--JUC package source Analysis--Exchanger source Analysis __exchanger

Source: Internet
Author: User

The synchronousqueue described in the previous article is a one-way data transfer between 2 threads, one put, one take.
And today's exchange, continue, is a two-way data transfer, 2 threads at a sync point, exchanging information.

Its use is roughly as follows:

Exchange<string> Exchange = new exchange<string> (); Build 1 + Threads shared Exchange objects

//Exchange objects, passed to 4 thread objects. Each thread, in its own run function, invokes exchange, passing its own data as a parameter, and the return value is the parameter that another thread calls Exchange to plug in.
Threada a = new Threada (Exchange);
Run ()
{
   String other = Exchange.exchange (self.data)  //No other thread calls exchange, blocking it. Until there are other threads calling Exchange.
}


THREADB B = new threadb (Exchange);
Run ()
{
   String other = Exchange.exchange (Self.data)
}


threadb c = new THREADC (Exchange);
Run ()
{
   String other = Exchange.exchange (Self.data)
}

threadc d = new Threadd (Exchange);
Run ()
{
   String other = Exchange.exchange (Self.data)
}

In the above example, 4 threads concurrently invoke Exchange and 22 interact with the data. May be A/b, C/D, may also A/C, b/d, or A/D, b/c. Exchange Implementation

From a simple point of view, Exchange needs only one mutex variable is enough. Because you can limit, at any time, only 1 pairs occur, not multiple pairs, and exchange occurs.

However, in order to increase concurrency, exchange internally uses multiple variables, within which they are called slot.

public class Exchanger<v> {

    private static final class Slot extends atomicreference<object> {
        long q0 , Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, QB, QC, QD, QE;

   Private volatile slot[] Arena = new Slot[capacity];
 }
Key technical points 1:cacheline filling

In the above code, slot is actually a atomicreference, its inside q0, Q1,.. QD Those variables, they are redundant, not necessary. So why add these extra variables?

is to allow different slot not to fall in the CPU of the same cacheline inside. Because the CPU reads data from memory, not a byte of reading, but by block read, here is the block is "cacheline", generally a cacheline size is 64Byte.

To ensure a slot size >= 64Byte, changing one slot will not cause another slot CPU cache to fail, thereby improving performance.

You know, slot is actually a atomicreference, here's a 2nd technical point. Key technology point 2: Lock Separation

With the Concurrenthashmap type, Exchange does not define only one slot, but instead defines an array of slot. This allows you to match each other in a different slot when you call Exchange in multiple threads.

The basic ideas for Exchange are as follows:
(1) According to each thread ID, hash calculated its own slot index;
(2) If the luck is good, this slot is occupied (slot inside has node), and someone is waiting for the exchange, then exchange with it;
(3) slot is empty (there is no node in slot), oneself occupy, wait for person exchange. No one to exchange, move forward position, the current slot inside content cancellation, index halved, see if there is exchange;
(4) Move to 0 this position, no one has interacted, then blocking, has been waiting. Other threads will also move until the 0 position.

So the 0 position is the "endpoint" position of a transaction. No one else in the position to trade, and finally will be 0 this position.

The following is the source code for Exchange:

    Public V Exchange (v x) throws Interruptedexception {if (! Thread.interrupted ()) {Object v = doexchange (x = = null?)
            Null_item:x, False, 0);
            if (v = = Null_item) return NULL;
            if (v!= CANCEL) return (v) v; Thread.interrupted ();
    Clear interrupt status on IE throw} throw new Interruptedexception ();                 
        Private Object Doexchange (object item, Boolean timed, long Nanos) {node me = new Node (item);                  int index = Hashindex ();                            

        Calculate where you want to go based on the thread ID (slot) int fails = 0; for (;;)                             
            {Object y;
            Slot Slot = Arena[index];     if (slot = = null) createslot (index); Slot = NULL, creates a slot, then returns to the For loop, starts again else if ((y = Slot.get ())!= null &&//slot There is someone waiting (with node) to try and
    Exchange                 Slot.compareandset (y, null)) {//Key point 1:slot Empty, node takes out, two people interact in node.               
                Give the slot to the people behind, do the interactive location node you = (node) y;
                    if (You.compareandset (null, item)) {//Replace the contents of node with its own locksupport.unpark (you.waiter);//Wake up each other return you.item;
            Take each other's things away.//Key point 2: If you are unlucky, when you want to swap in node, be robbed by another thread, go back to the For loop, start again} else if (y = = null &&//slot inside is empty (no node), then take the position to occupy Slot.compareand Set (null, ME) {if (index = 0)///If 0 is in this position, block yourself and wait for someone else to exchange return time D?
                Awaitnanos (Me, slot, Nanos): Await (me, slot);    Object v = spinwait (me, slot);
                Not 0 This position, spin wait if (v!= CANCEL)/Spin wait time, good luck, someone to exchange, returned return V;     me = new Node (item); When the spin, no one to exchange. Go perform the following, index by half, move position, restart for loop int m = mAx.get (); 
            if (M > (index >>>= 1)) Max.compareandset (M, m-1); else if (++fails > 1) {//failure case1:slot Someone, to interact, but was robbed Case2:slot no one, their own position, and was robbed in
                T m = Max.get ();   if (Fails > 3 && m < full && max.compareandset (M, M + 1)) index = m + 1;                   
            3 times match failed, expand Index, start again for loop else if (--index < 0) index = m; }
        }
    }

Note: The only thing that goes a little around here is a node in the slot. The location of the two parties, accurately speaking, is not in the slot inside, is in slot node inside.
When slot node = null, the representative slot is empty, a new node is occupied;
When the slot node. = NULL when the node is taken out, the two sides in node exchange, at this time slot has been released. Summary

Exchanger's code, although less, but still quite around, summed up, there are several key points:
(1) Cache Line filling Technology
(2) Lock separation
(3) The two people have not exchanged the end of the time, the slot to release. The two sides take that node and interact in the node. Which is the 2nd branch of the for loop above.
One of the things is: bad luck, 2 people are going to be in the node in Exchange, by another thread robbed. Well, this one didn't grab it, just for the loop, start over.
(4) 0 is the endpoint location of the exchange: when no one exchanges, will constantly move the position, move, to the current position of the slot empty, a person can not account for 2 slot. Until you move to the 0 position and wait.

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.