Java and send package query set

package java.util.concurrent
Copy the code

1. The lock bag

  • ReenTrantLock
  • ReenTrantWriteReadLock

2. The atomic package

  • AtomicInteger
  • LongAdder

3. Concurrency helper classes

  • CountDownLatch (AKA: Starting Gun \ Countdown Lock)
    • An overview of

      • Take a look at the source code comments
        /** * A synchronization aid that allows one or more threads to wait until * a set of operations being performed in other  threads completes. * *@since 1.5
        * @author Doug Lea
         */
        public class CountDownLatch {}Copy the code

      It is a synchronization utility class that allows one or more threads to wait until other threads have finished executing. Through the description, it can be clearly seen that CountDownLatch is used in two scenarios:

      • Scenario 1: Make multiple threads wait
      • Scenario 2: And make a single thread wait.
    • usage

      • Scenario 1: Let multiple threads wait: Simulate concurrency and let concurrent threads execute together

        package com.zly.concurrent;
        
        import java.util.concurrent.CountDownLatch;
        
        public class useCountDownLatch {
            public static void main(String[] args) throws Exception{
                useCountDownLatch useCountDownLatch = new useCountDownLatch();
                useCountDownLatch.multiThreadWait();
            }
        
            public void multiThreadWait(a) throws Exception{
                CountDownLatch countDownLatch = new CountDownLatch(1);
        
                int i = 0;
                do{
                    new Thread(() -> {
                        try {
                        	// The players are all jammed here, waiting for the start
                            countDownLatch.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("currentThread start run");
                    }).start();
                    i ++;
                }while (i < 5);
        
                System.out.println("before run");
                Thread.sleep(2000);// The referee is ready to give the call
                countDownLatch.countDown();// Starting gun: execute the command}}Copy the code

        Running results:

        before run currentThread start run currentThread start run currentThread start run currentThread start run currentThread  start runCopy the code
      • Scenario 2: Let a single thread (such as the main thread) wait: When multiple threads (tasks) are complete, merge them

        public void singleThreadWait(a) throws Exception{
        CountDownLatch countDownLatch = new CountDownLatch(5);
        for (int i = 1; i <= 5; i++) {
        	final int index = i;
        	new Thread(() -> {
            	try {
                	Thread.sleep(1000 + ThreadLocalRandom.current().nextInt(1000));
                	System.out.println("finish:" + index + Thread.currentThread().getName());
                  	countDownLatch.countDown();
              	} catch (InterruptedException e) {
                  	e.printStackTrace();
              	}
          	}).start();
        	}
        
            countDownLatch.await();// The main thread is blocking, and when the counter ==0, it wakes up the main thread to proceed.
            System.out.println("Main thread: Summary of results after all tasks are completed.");
        }
        Copy the code

        Running results:

        Finish: 1thread-5 Finish: 5thread-9 Finish: 4thread-8 Finish: 3thread-7 Finish: 2thread-6 Main thread: Summarizes the results after all tasks are completedCopy the code
        • For example, when a springBoot project starts, you don’t want the main thread to stop until the Spring thread has finished processing it
        @SpringBootApplication
        public class Main {
        
            private static final Logger logger = LoggerFactory.getLogger(Main.class);
        
            private static CountDownLatch closeLatch = new CountDownLatch(1);
        
            public static void main(String[] args) throws InterruptedException {
                new SpringApplicationBuilder()
                    .sources(Main.class)
                    .web(false)
                    .run(args);
                logger.info("admin service start ok.");
                closeLatch.await();
            }
        
        Copy the code
    • Train of thought

      • CountDownLatch is implemented through a counter whose initial value is the number of threads; The thread calling the await() method will block until the counter reaches zero before it can proceed;

      • Await () is called to block the waiting thread, which blocks on the Latch Latch/fence; They can pass the fence at the same time only if the condition is countered (countDown() N times, reducing the count to 0); This can be done so that all threads stand on a starting line.

    • The principle of
      • Based on the underlying AbstractQueuedSynchronizer implementation, CountDownLatch count) specified in the constructor directly assigned to AQS state;
      • CountDown () will countDown(1) to release(1), and unpark blocks when it reaches 0; This step is performed by the last thread to execute the countdown method.
      • When the await() method is called, the current thread determines whether the state property is 0, and if so, continues execution
      • If it is not 0, the current thread is put into wait state until a thread sets the state property to 0, which wakes up the thread waiting in the await() method.
    • contrast
      • Vs CyclicBarrier CountDownLatch and CyclicBarrier both implement waits between threads, but they have different priorities: CountDownLatch is typically used by one or more threads waiting for the other threads to complete their task before executing a CyclicBarrier. CountDownLatch is typically used by a group of threads waiting for each other to complete their task before executing a CyclicBarrier. Cannot reuse after count is reduced to 0; CyclicBarrier is an additive count, which can be set to 0 and reused.
      • Vs Thread.join CountDownLatch allows one or more threads to wait for other threads to complete. This looks similar to the join() method, but provides a more flexible API than join(). CountDownLatch can manually control whether the countDown() method is called n times in n threads to decrement the counter, or it can be called n times in a thread to decrement the counter. Join () is implemented by constantly checking to see if the join thread is alive, and if so, making the current thread wait forever. So CountDownLatch is relatively flexible between the two.
  • Semphare(AKA: Semaphore)
  • CyclicBarrier(AKA: Circular barrier)
    • A loop refers to a CyclicBarrier that can be reused after all waiting threads have been released

      • CyclicBarrier counters have an automatic reset function, which automatically resets your initial value when it drops to zero. This feature is extremely convenient to use.
    • A fence is when you lock up multiple threads and make everyone wait

    • Overview of the source code comments as follows:

      
      /* A synchronization aid that allows a set of threads to all wait foreach other to reach a common barrier point. CyclicBarriers areuseful in programs involving a fixed sized party of threads thatmust occasionally wait for each other.  The barrier is called cyclic because it can be re-used after the waiting threads are released. */
      Copy the code
    • usage

      • The callback

        The second constructor of CyclicBarrier:
        CyclicBarrier(int parties, Runnable barrierAction);
        Copy the code

        BarrierAction can specify a cleanup task to be executed when everyone reaches the barrier point.

        • CyclicBarrier’s callback function, which can specify a thread pool to run asynchronously;
        • If no thread pool is specified, it defaults to the last thread to execute await(), which equals synchronization completion.
      
         package com.zly.concurrent;
      
         import java.util.concurrent.CyclicBarrier;
      
         public class useCyclicBarrier {
             static int state = 1;
             static int total = 5;
             public static void main(String[] args) {
      
      
               CyclicBarrier cyclicBarrier = new CyclicBarrier(total, new Runnable() {
                   @Override
                   public void run(a) {
                       System.out.println("Complete" + state + "Stage!! -- -- -- -- -- -"); state ++; }});for(int i = 0; i< total; i++){
                   new Thread( () -> {
                       String name = Thread.currentThread().getName();
                       try {
                           //1. Morning meetings at work
                           System.out.println("Morning meeting at work." + name);
      
                           cyclicBarrier.await();
      
                           // Get ready
      
                           //2. Start work
                           System.out.println("Work ing ~" + name);
                           // Assemble for dinner
                           cyclicBarrier.await();
                           / / 3. To eat
                           System.out.println("Dinner!!" + name);
                       }catch(Exception e){ e.printStackTrace(); } }).start(); }}}Copy the code

      Running results:

      ~Thread-0 ~Thread-3 ~Thread-2 ~Thread-1 ~Thread-4 Complete stage 1! ------ work ing~ thread-4 work ing~ thread-2 work ing~ thread-1 work ing~ thread-0 work ing~ thread-3 complete stage 2!! ------ have a meal!! Thread-3 is eating!! Thread-4 is eating!! Thread-2 has eaten!! Thread-0 has eaten!! Thread-1Copy the code
    • The principle is based on ReentrantLock and Condition

      /** The lock for guarding barrier entry */
      private final ReentrantLock lock = new ReentrantLock();
      /** Condition to wait on until tripped */
      private final Condition trip = lock.newCondition();
      /** The number of parties */
      private final int parties;
      /* The command to run when tripped */
      private final Runnable barrierCommand;
      /** The current generation */
      private Generation generation = new Generation();
      Copy the code

      The core logic is to lock with ReentrantLock in dowait(), each time await(), –count; Until count==0 triggers the update logic

      private int dowait(boolean timed, long nanos){
      
          / / to omit
          int index = --count;
          if (index == 0) {  // tripped
              boolean ranAction = false;
              try {
                  final Runnable command = barrierCommand;
                  if(command ! =null)
                      command.run();
                  ranAction = true;
                  nextGeneration();
                  return 0;
              } finally {
                  if (!ranAction)
                      breakBarrier();
              }
          }
          / / to omit
      }
      Copy the code

      Replacement logic

      private void nextGeneration(a) {
          // signal completion of last generation
          trip.signalAll();
          // set up next generation
          count = parties;
          generation = new Generation();
      }
      Copy the code
    • In some cases, a barrier may be broken and any thread waiting on the barrier will be released. See CyclicBarrier’s BrokenBarrierException

4. Task

  • Callable interface
    • To solve the problem of Thread and Runnable not returning results
    • It is possible to obtain the results indirectly by sharing variables or thread communication, but my level is probably 996 bug solving. Fortunately, it’s been encapsulated by Professor Doug Lea
    • Runnble can be adapted to Callable objects using the RunnableAdapter adapter
  • The Future interface
    • A Future is a bridge between the caller and the asynchronous executor. Callable/Runnable is created to work with Callable/Runnable. What does Callable return? When will it return? These are handled by the Future and placed on the upper thread’s stack for it to decide.
    • Compare that to Runnable and Callable
      • The Runnable interface comes with jdk1.0, under the java.lang package
      • The Callable and Future interfaces are both under the java.util.concurrent package and are enhancements to Runnable functionality by Doug Lea in jdk1.5
  • RunnableFuture
  • FutureTask

    Also written by professor Doug Lea in jdk1.5, it can be used to wrap Runnable and Future

    FutureTask implements the RunnableFuture interface and has both Runnable and Future capabilities, that is, it can return a Callable value as a Future, and it can be used as a Runnable.

5.Executor

  • Executor Interface The Executor interface is the highest level interface in the thread pool. This interface has only one method, which abstracts the core action.

    void execute(Runnable command);
    Copy the code

    Note that only the most basic Runnable is supported

  • ExecutorService interface (Extend Executor) The execute() method of Executor, although a minimalist design, often fails to meet our needs, such as:

    • The return result of the task is required
    • Batch Submitting Tasks

    The method is as follows:

    • The three submit() methods handle Callable, Runnable, and the case where the task is Runnable and the return value is expected
    • Both invokeAll() methods accept Callable in the form of a collection, but one can pass a timeout
      • Returns the Future of all tasks in the collection
    • One of the two invokeAny() methods also invokes a timeout
      • Returns the result of only one task (Is not the Future), the resultrandomIt could be the result of the first task, it could be the result of the middle task, it could be the result of the last task
  • AbstractExecutorService implements the ExecutorService interface

    • The principle of todo
  • Executors

  • CompletionService

  • Fork-join

  • Phaser

  • Exchanger

  • ThreadFactory

The resources

1.There are two common scenarios for CountDownLatch

2.CyclicBarrier is a powerful tool for multi-task collaboration