Java Concurrency Foundation-concurrency tool Class (i)

Source: Internet
Author: User
Tags semaphore java se
Concurrency tool classes

This series of articles mainly on Java concurrency related content, including synchronization, lock, semaphore, blocking queue, thread pool, etc., the overall mind map as follows:

Series of articles list:

    • Java Concurrency Foundation-concurrency model, base interface, and thread
    • Java Concurrency Basics-synchronization and locks

In this paper, the main examples are explained CountDownLatch , Semaphore blocking queues and thread pool and other content.

Countdownlatch Basic concepts and uses

CountDownLatchThe primary is to allow one or more threads to wait until the other thread executes the operation.
Its source code implementation is mainly used AQS , specific reference to the Java concurrent basis-synchronization and lock.
The constructor method CountDownLatch ( int count ) is used to initialize the counter, which is actually count state the initial value of the set (eventually the set value). After the value is set, it cannot be reset, and it can be used instead when the thread must repeatedly count down in this way CyclicBarrier .
countDown()method is used to reduce the value of the counter, minus each time 1 .
getCount()method is used to return the value of the current counter.
The flowchart is simplified as follows

Run the sample

In the Synchronizeddemo code, we use the join method of Thread to wait for a spender and After the earner thread finishes running, get the value of the account balance balance , where we use the Countdownlatch counter to block the main thread for a set After Spender and a set of earner threads are complete, let the main thread get the value of the account balance, as follows:

Package Com.molyeo.java.concurrent;import Java.util.concurrent.countdownlatch;import Java.util.concurrent.executorservice;import java.util.concurrent.executors;/** * Created by Zhangkh on 2018/7/17. */public class Countdownlatchdemo {public static void main (string[] args) throws Interruptedexception {System.        Out.println ("Main thread start");        Account Account = new account ();        Account.setbalance (100000);        Countdownlatch latch = new Countdownlatch (20);        System.out.println ("Main latch init=" +latch.getcount ());        Executorservice Executorservice = Executors.newfixedthreadpool (10); for (int i = 0; i < i++) {Spenderwithcountdownlatch spender = new Spenderwithcountdownlatch (account, LA            TCH);        Executorservice.submit (spender); } for (int i = 0; i < i++) {Earnerwithcountdownlatch earner = new Earnerwithcountdownlatch (accou            NT, latch);        Executorservice.submit (earner);      }  System.out.println ("Main thread block");        Latch.await ();        System.out.println ("Main latch=" +latch.getcount ());        System.out.println ("Main thread continue to do");        System.out.println ("balance=" +account.getbalance ());    Executorservice.shutdown (); }}

The first initialized CountDownLatch value is 20 , and then the distribution creates a set of Spender threads (each group 10 ) and a set of Earner threads (each group 10 ), and account latch passes them to those threads.

SpenderWithCountDownLatchThe code below, the main time the operation is 30 to reduce the account balance, each decrease 1000 . Called when the run latch countDown() is complete, reducing the value of the counter.

public class SpenderWithCountDownLatch implements Runnable {    private final Account account;    private final CountDownLatch latch;    public SpenderWithCountDownLatch(Account account, CountDownLatch latch) {        this.account = account;        this.latch = latch;    }    @Override    public void run() {        for (int i = 0; i < 30; i++) {            account.subtractAmount(1000);        }        latch.countDown();        System.out.println("Spender run ......");    }}

EarnerWithCountDownLatchThe code below, the runtime is mainly the 30 second increase in the account balance, each increase 1000 . Called when the run latch countDown() is complete, reducing the value of the counter.

public class EarnerWithCountDownLatch implements Runnable {    private final Account account;    private final CountDownLatch latch;    public EarnerWithCountDownLatch(Account account, CountDownLatch latch) {        this.account = account;        this.latch = latch;    }    @Override    public void run() {        for (int i = 0; i < 30; i++) {            account.addAmount(1000);        }        latch.countDown();        System.out.println("Earner run ...." );    }}

AccountThe code below needs to take advantage of synchronization blocks or Lock guarantees addAmount and subtractAmount methods for thread safety

public class Account {    private double balance;    public double getBalance() {        return balance;    }    public void setBalance(double balance) {        this.balance = balance;    }    public void addAmount(double amount) {        synchronized (Account.class) {            balance = balance + amount;        }    }    public void subtractAmount(double amount) {        synchronized (Account.class) {            balance = balance - amount;        }    }}

The entire program output is as follows:

main thread startmain latch init=20main thread blockSpender run ......Spender run ......Spender run ......Earner run ....Earner run ....Earner run ....Earner run ....Earner run ....Earner run ....Spender run ......Earner run ....Earner run ....Spender run ......Earner run ....Earner run ....Spender run ......Spender run ......Spender run ......Spender run ......Spender run ......main latch=0main thread continue to dobalance=100000.0

Satisfies the expected result 100000 , while the main thread blocks until latch the value is 0 .

Cyclicbarrier basic concepts and main methods

CyclicBarrierAllows a group of threads to wait for each other until all threads reach the public barrier point ( common barrier point ). And CountDownLatch the difference is that it CyclicBarrier can be reset and reused after releasing the waiting thread.

Construction method

 public CyclicBarrier(int parties, Runnable barrierAction)

Which parties represents the number of threads, that is, the number of participants
barrierActionRepresents the barrier execution of the specified action at startup, which is performed by the last incoming barrier thread
Await ()
Participants are blocked waiting until all the participants arrivebarrier
The flowchart is simplified as follows

Using the example

Let's take a look at the following example, where the main thread, Spender thread, and Earner thread share one barrier , where the barrier initial value is 3 that three threads arrive barrier after BarrierAction the defined action is executed.

Package Com.molyeo.java.concurrent;import Java.util.concurrent.brokenbarrierexception;import Java.util.concurrent.cyclicbarrier;import Java.util.concurrent.executorservice;import java.util.concurrent.executors;/** * Created by Zhangkh on 2018/9/5.        */public class Cyclicbarrierdemo {public static void main (string[] args) {account account=new account ();        Account.setbalance (100000);        Cyclicbarrier barrier = new Cyclicbarrier (3, New barrieraction ());        Executorservice Executorservice = Executors.newfixedthreadpool (10);        Spenderwithcyclicbarrier spender = new Spenderwithcyclicbarrier (account, barrier);        Executorservice.submit (spender);        Earnerwithcyclicbarrier earner = new Earnerwithcyclicbarrier (account, barrier);        Executorservice.submit (earner);            try{System.out.println (String.Format ("%20s waiting at Barrier", Thread.CurrentThread (). GetName ()));        Barrier.await ();          }catch (Interruptedexception e) {  E.printstacktrace ();        }catch (brokenbarrierexception e) {e.printstacktrace ();        } System.out.println ("Balance=" +account.getbalance ());    System.out.println (String.Format ("%20s Done", Thread.CurrentThread (). GetName ())); }}class Barrieraction implements runnable{public void run () {System.out.println (String.Format ("%20s executed",    Thread.CurrentThread (). GetName ());    }}class Spenderwithcyclicbarrier implements Runnable {private final account account;    Private final cyclicbarrier barrier;        Public Spenderwithcyclicbarrier (account account, Cyclicbarrier barrier) {this.account = account;    This.barrier = barrier;        } @Override public void Run () {for (int i = 0; i <; i++) {account.subtractamount (1000); } try{System.out.println (String.Format ("%20s waiting at Barrier", Thread.CurrentThread (). GetName ()            ));        Barrier.await (); }catch (interruptedexceptione) {e.printstacktrace ();        }catch (brokenbarrierexception e) {e.printstacktrace ();    } System.out.println (String.Format ("%20s Done", Thread.CurrentThread (). GetName ()));    }}class Earnerwithcyclicbarrier implements Runnable {private final account account;    Private final cyclicbarrier barrier;        Public Earnerwithcyclicbarrier (account account, Cyclicbarrier barrier) {this.account = account;    This.barrier = barrier;        } @Override public void Run () {for (int i = 0; i <; i++) {account.addamount (1000);            } try{System.out.println (String.Format ("%20s waiting at Barrier", Thread.CurrentThread (). GetName ()));        Barrier.await ();        }catch (interruptedexception e) {e.printstacktrace ();        }catch (brokenbarrierexception e) {e.printstacktrace ();    } System.out.println (String.Format ("%20s Done", Thread.CurrentThread (). GetName ())); }}class ACcount {private double balance;    Public double GetBalance () {return balance;    } public void Setbalance (double balance) {this.balance = balance;        } public void Addamount (double amount) {synchronized (account.class) {balance = balance + amount; }} public void Subtractamount (double amount) {synchronized (account.class) {balance = Bal        Ance-amount; }    }}

The program output is as follows:

 pool-1-thread-2 waiting at barrier            main waiting at barrier pool-1-thread-1 waiting at barrier pool-1-thread-1 executed pool-1-thread-1 done pool-1-thread-2 done balance=100000.0            main done

We can see-- pool 1 thread 2 and after the main thread executes the operation on the balance of the account, it arrives at the blocking wait,---the barrier pool 1 thread 1 thread finally arrives, then by pool - 1 - thread - 1 The thread executes the predefined action, that is executed , after the output, the three threads continue to execute the output of the other information.
Notice here that the output may be inconsistent, but the thread names on the third and fourth lines are either, or--or--- main pool 1 thread 1 pool 1 thread 2 . There is no case where two thread names are different. This shows that the barrier predefined action after arrival is performed by the last thread that arrives.

This article references

Java 7 Concurrency Cookbook

Concurrency-modle-seven-week

Java-concurrency

Java-util-concurrent

Java SE 8 Apidoc

About the author
Love programming, love studying, love sharing, love life
Focus on distributed, high concurrency, data mining
If you want to donate, please scan the code

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.