Multithreaded high concurrency JUC programming

“This is the 29th day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.

About the author

  • The authors introduce

🍓 blog home page: author’s home page 🍓 Introduction: JAVA quality creator 🥇, a junior student 🎓, participated in various provincial and national competitions during school, and won a series of honors


5, 8 Lock phenomenon

1-2 lock

package com.zmz.lock8;/ * * *@ProjectName: Juc
 * @Package: com.zmz.lock8
 * @ClassName: Test1
 * @Author: Shengrui Zhang *@Date: 2021/9/5 material *@Version: 1.0 * /

import java.util.concurrent.TimeUnit;

/ * * *@ClassName Test1
 *@Description
 *@AuthorZhang Shengrui *@Date2021/9/5 * * /
1, Under standard conditions, two lines print first send SMS or make a call? SendSms * 2. The sendSms method is delayed by 4s. Print the two lines first to sendSms or make a phone call? Text * */
public class Test1 {
    public static void main(String[] args) {
        Phone phone = new Phone();

        / / lock
        new Thread(()->{
            phone.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start(); }}class Phone{

    // Synchronized lock objects are method callers!
    // Both methods use the lock of the phone object!
    // The one who gets it first executes!
    public synchronized void sendSms(a){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Texting");
    }
    public synchronized void call(a){
        System.out.println("Make a call"); }}Copy the code

3-4 lock

package com.zmz.lock8;/ * * *@ProjectName: Juc
 * @Package: com.zmz.lock8
 * @ClassName: Test2
 * @Author: Shengrui Zhang *@Date: 2021/9/5 21:26
 * @Version: 1.0 * /

import java.util.concurrent.TimeUnit;

/ * * *@ClassName Test2
 *@Description
 *@AuthorZhang Shengrui *@Date2021/9/5 * * /
//3, add a normal method after! Text or Hello? Text Hello
//4, two objects, two synchronization methods, SMS or call
public class Test2 {
    public static void main(String[] args) {
        // Two objects, two locks
        Phone2 phone = new Phone2();
        Phone2 phone2 = new Phone2();

        / / lock
        new Thread(()->{
            phone.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start(); }}class Phone2{

    // Synchronized lock objects are method callers!

    public synchronized void sendSms(a){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Texting");
    }
    public synchronized void call(a){
        System.out.println("Make a call");
    }

    // There is no lock here! Bubu is not a synchronous method and is not affected by locks
  public void hello(a){
        System.out.println("hello"); }}Copy the code

5-6 lock

package com.zmz.lock8;/ * * *@ProjectName: Juc
 * @Package: com.zmz.lock8
 * @ClassName: Test3
 * @Author: Shengrui Zhang *@Date: 2021/9/6 treasure *@Version: 1.0 * /

import java.util.concurrent.TimeUnit;

/ * * *@ClassName Test3
 *@Description
 *@AuthorZhang Shengrui *@Date2021/9/6 * * /
/* * 5, add two static synchronization methods, only one object, first print SMS or call? Send text messages * 6, two objects! Add two static synchronization methods, only one object, first print SMS or call SMS * */
public class Test3 {
    public static void main(String[] args) {
        // Two objects, two callers, two locks!
        // There is only one class template for two objects
        Phone3 phone = new Phone3();
        Phone3 phone2 = new Phone3();
        / / lock
        new Thread(()->{
            phone.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start(); }}//Phone3 has a unique Class object
class Phone3{

    // Synchronized lock objects are method callers!
    //static static method
    // The class is available as soon as it is loaded. The Class template locks the Class
    public static synchronized void sendSms(a){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Texting");
    }
    public static synchronized void call(a){
        System.out.println("Make a call"); }}Copy the code

7-8 locks

package com.zmz.lock8;/ * * *@ProjectName: Juc
 * @Package: com.zmz.lock8
 * @ClassName: Test4
 * @Author: Shengrui Zhang *@Date: 2021/9/6 13:07
 * @Version: 1.0 * /

import java.util.concurrent.TimeUnit;

/ * * *@ClassName Test4
 *@Description
 *@AuthorZhang Shengrui *@Date2021/9/6 * * /
/* * 1 static synchronization method, 1 synchronization method, 1 object call first SMS or call? Call * 1 static synchronization method, 1 synchronization method, 2 objects call first print SMS or call? Text * */
public class Test4 {
    public static void main(String[] args) {
        // Two objects, two callers, two locks!
        // There is only one class template for two objects
        Phone4 phone = new Phone4();
        / / lock
        new Thread(()->{
            phone.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start(); }}//Phone4 has a unique Class object
class Phone4{

    // Synchronized lock objects are method callers!
    // Lock the Class template
    public static synchronized void sendSms(a){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Texting");
    }
    // Lock the caller
    public synchronized void call(a){
        System.out.println("Make a call"); }}Copy the code

6. Collection is not safe

1. ArrayList collections are not secure

package com;/ * * *@ProjectName: Juc
 * @Package: com
 * @ClassName: unsafe
 * @Author: Shengrui Zhang *@Date: 2021/9/6 for *@Version: 1.0 * /

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/ * * *@ClassName unsafe
 *@Description
 *@AuthorZhang Shengrui *@Date2021/9/6 * * /
public class unsafe {
    public static void main(String[] args) {
        // Is ArrayList safe with high concurrency?
        List
      
        List = new Vector
       
        (); * 2, a List < String > List = Collections. SynchronizedList (new ArrayList < > ()); * 3, List
        
          List = new CopyOnWriteArrayList<>(); * * /
        
       
      
        List<String> list = new CopyOnWriteArrayList<>();
        // Start 10 threads
        for (int i = 1; i < 10; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0.5)); System.out.println(list); }, String.valueOf(i)).start(); }}}Copy the code

CopyOnWriteArrayList source code analysis

2. Set is not safe

package com.zmz.unsafe;/ * * *@ProjectName: Juc
 * @Package: com.zmz.unsafe
 * @ClassName: SetSafe
 * @Author: Shengrui Zhang *@Date: 2021/9/6 * mark@Version: 1.0 * /

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;

/ * * *@ClassName SetSafe
 *@Description
 *@AuthorZhang Shengrui *@Date2021/9/6 * * /
public class SetSafe {
    public static void main(String[] args) {
        //Set<String> set = new HashSet<>();
        //Set<String> set = Collections.synchronizedSet(new HashSet<>());
        Set<String> set = new CopyOnWriteArraySet<>();
        for (int i = 1; i < 60; i++) {
            new Thread(() -> {
                set.add(UUID.randomUUID().toString().substring(0.5)); System.out.println(set); }, String.valueOf(i)).start(); }}}Copy the code

HashSet source

    public HashSet(a) {
        map = new HashMap<>();
    }

  // A HashSet is essentially a Map set
  public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

private static final Object PRESENT = new Object();// Constant value
Copy the code

3. HashMap is not secure

package com.zmz.unsafe;/ * * *@ProjectName: Juc
 * @Package: com.zmz.unsafe
 * @ClassName: MapSafe
 * @Author: Shengrui Zhang *@Date: 2021/9/6 use *@Version: 1.0 * /

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/ * * *@ClassName MapSafe
 *@Description
 *@AuthorZhang Shengrui *@Date2021/9/6 * * /
public class MapSafe {
    public static void main(String[] args) {
        //Map<String,String> map = new HashMap<>();
        //Map<String, Object> map = Collections.synchronizedMap(new HashMap<>());
        Map<String, Object> map = new ConcurrentHashMap<>();

        for (int i = 1; i <= 30; i++) {
            new Thread(()->{
                map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0.5)); System.out.println(map); },String.valueOf(i)).start(); }}}Copy the code

7, Callable

  1. You can have a return value
  2. You can throw an exception
  3. Different methods, run()/call()

Callable source

The test code

package com.zmz.callable;/ * * *@ProjectName: Juc
 * @Package: com.zmz.callable
 * @ClassName: CallableTest
 * @Author: Shengrui Zhang *@Date: 2021/10/3 hast judged *@Version: 1.0 * /

import com.sun.org.apache.bcel.internal.generic.NEW;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/ * * *@ClassName CallableTest
 *@Description
 *@AuthorZhang Shengrui *@Date2021/10/3 * * /
public class CallableTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // new Thread(new Runnable()).start();
        // new Thread(new FutureTask<V>()).start();
        // new Thread(new FutureTask<V>( Callable )).start();

        new Thread().start();

        MyThread myThread = new MyThread();
        FutureTask futureTask = new FutureTask(myThread);/ / class

        new Thread(futureTask,"A").start();
        new Thread(futureTask,"B").start(); // The result has cache commit efficiency
        Integer o = (Integer) futureTask.get();// Get the result returned
        // The get method can block! The solution is to put it on the last line or communicate asynchronouslySystem.out.println(o); }}class MyThread implements Callable<Integer>{

    @Override
    public Integer call(a) throws Exception {
        System.out.println("The call () method." ");
        // Time consuming operation
        return 1024; }}/* the result may wait, blocking */
Copy the code

8. Commonly used auxiliary classes

1) CountDownLatch — Subtraction counter

package com.zmz.assist;/ * * *@ProjectName: Juc
 * @Package: com.zmz.assist
 * @ClassName: CountDownLatchDemo
 * @Author: Shengrui Zhang *@Date: 2021/10/3 18:00
 * @Version: 1.0 * /

import java.util.concurrent.CountDownLatch;

/ * * *@ClassName CountDownLatchDemo
 *@Description
 *@AuthorZhang Shengrui *@Date2021/10/3 * * /
public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch count = new CountDownLatch(10);
        for (int i = 1; i <= 10; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName() + "Go out");
                count.countDown();/ / the number 1
            },String.valueOf(i)).start();

        }
        count.await();// Wait for the counter to return to zero, then proceed
        System.out.println("Close Door"); }}Copy the code

Principle:

  • count.countDown(); / / the number 1
  • count.await(); // Wait for the counter to return to zero. And then we go down

CountDown () counts -1 every time a thread countDown() counts -1, if the calculator goes to 0, then count.await() is woken up and continues!

2) CyclicBarrier – addition counter

package com.zmz.assist;/ * * *@ProjectName: Juc
 * @Package: com.zmz.assist
 * @ClassName: CycilcBarrierDemo
 * @Author: Shengrui Zhang *@Date: 2021/10/3 when *@Version: 1.0 * /

import com.sun.org.apache.bcel.internal.generic.NEW;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/ * * *@ClassName CycilcBarrierDemo
 *@Description
 *@AuthorZhang Shengrui *@Date2021/10/3 * * /
public class CycilcBarrierDemo {
    public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
        CyclicBarrier barrier = new CyclicBarrier(7,()->{
            System.out.println("You've got seven dragon balls! You can change.");
        });

        for (int i = 1; i <= 7; i++) {
            final int temp = i;
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+ "Collect" +(temp) +"Dragon Ball");
                try {
                    barrier.await();/ / wait for
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch(BrokenBarrierException e) { e.printStackTrace(); } }).start(); }}}Copy the code

3) Semaphore

Semaphore: A Semaphore, often used to handle high concurrency.

package com.zmz.assist;/ * * *@ProjectName: Juc
 * @Package: com.zmz.assist
 * @ClassName: SemaphoreDemo
 * @Author: Shengrui Zhang *@Date: bank against 2021/10/3 *@Version: 1.0 * /

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/ * * *@ClassName SemaphoreDemo
 *@Description
 *@AuthorZhang Shengrui *@Date2021/10/3 * * /
public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);
        for (int i = 1; i <= 6; i++) {
            new Thread(()->{
                try {
                    semaphore.acquire();/ / get
                    System.out.println(Thread.currentThread().getName()+"Get a parking space.");
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println(Thread.currentThread().getName()+"Leave the parking space.");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }   finally {
                    semaphore.release();/ / release} },String.valueOf(i)).start(); }}}Copy the code

Principle:

  • Acquire () : if the group is full, wait until it is released

  • Release () : releases the current semaphore +1 and wakes up the waiting thread!

    Function: Multiple shared resources are mutually exclusive! Concurrency limiting controls the maximum number of threads!

9. ReadwriteLock

package com.zmz.lock;/ * * *@ProjectName: Juc
 * @Package: com.zmz.lock
 * @ClassName: ReadwritelockDemo
 * @Author: Shengrui Zhang *@Date: 2021/10/3 all *@Version: 1.0 * /

import java.util.HashMap;
import java.util.Map;

/ * * *@ClassName ReadwritelockDemo
 *@Description
 *@AuthorZhang Shengrui *@Date2021/10/3 * * /
public class ReadwritelockDemo {
    public static void main(String[] args) {
        Mycache mycache = new Mycache();
        / / write
        for (int i = 1; i < 6; i++) {
            final int temp = i;
            new Thread(()->{
                mycache.put(temp+"",temp+"");
            },String.valueOf(i)).start();
        }
        / / read
        for (int i = 1; i < 6; i++) {
            final int temp = i;
            new Thread(()->{
                mycache.get(temp+""); },String.valueOf(i)).start(); }}}class Mycache{
    private volatile Map<String , Object> map = new HashMap<>();
    public void put(String key, Object value){
        System.out.println(Thread.currentThread().getName() + "Written" + key);
        map.put(key,value);
        System.out.println(Thread.currentThread().getName() + "Write complete");
    }

    public void get(String key){
        System.out.println(Thread.currentThread().getName() + "Read" + key);
        Object o = map.get(key);
        System.out.println(Thread.currentThread().getName() + "Read completed"); }}/* 1 Write 1 5 Write 5 5 Write complete 4 Write 4 4 Write complete 3 Write 3 2 Write 2 1 Read 1 3 Write complete 1 Write Complete 2 Read 2 Read complete 3 read 3 read complete 1 Read Complete 2 Write Complete 5 Read 5 Read complete 4 Read 4 Read complete */
Copy the code

We can see that there is a serious queue-jumping problem! How to solve the sac? We use read/write locks to solve queue-jumping problems.

Modified operations

package com.zmz.lock;/ * * *@ProjectName: Juc
 * @Package: com.zmz.lock
 * @ClassName: ReadwritelockDemo
 * @Author: Shengrui Zhang *@Date: 2021/10/3 all *@Version: 1.0 * /

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/ * * *@ClassName ReadwritelockDemo
 * @Description
 * @AuthorZhang Shengrui *@Date2021/10/3 * * /

/* * Exclusive lock (write lock) can only be held by one thread at a time * Shared lock (read lock) Multiple threads can hold * ReadWriteLock * Read-read can coexist * read-write cannot coexist * write-write cannot coexist * */
public class ReadwritelockDemo {
    public static void main(String[] args) {
        MycacheLock mycache = new MycacheLock();
        / / write
        for (int i = 1; i < 6; i++) {
            final int temp = i;
            new Thread(() -> {
                mycache.put(temp + "", temp + "");
            }, String.valueOf(i)).start();
        }
        / / read
        for (int i = 1; i < 6; i++) {
            final int temp = i;
            new Thread(() -> {
                mycache.get(temp + ""); }, String.valueOf(i)).start(); }}}/ / lock
class MycacheLock {
    private volatile Map<String, Object> map = new HashMap<>();
    // Read/write locks: more fine-grained control
    ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    // Only one thread can write at the same time
    public void put(String key, Object value) {
        readWriteLock.writeLock().lock();

        try {
            System.out.println(Thread.currentThread().getName() + "Written" + key);
            map.put(key, value);
            System.out.println(Thread.currentThread().getName() + "Write complete");
        } catch (Exception e) {
            e.printStackTrace();
        } finally{ readWriteLock.writeLock().unlock(); }}// All users can read and write
    public void get(String key) {
        readWriteLock.readLock().lock();

        try {
            System.out.println(Thread.currentThread().getName() + "Read" + key);
            Object o = map.get(key);
            System.out.println(Thread.currentThread().getName() + "Read completed");
        } catch (Exception e) {
            e.printStackTrace();
        } finally{ readWriteLock.readLock().unlock(); }}}class Mycache {
    private volatile Map<String, Object> map = new HashMap<>();

    public void put(String key, Object value) {
        System.out.println(Thread.currentThread().getName() + "Written" + key);
        map.put(key, value);
        System.out.println(Thread.currentThread().getName() + "Write complete");
    }

    public void get(String key) {
        System.out.println(Thread.currentThread().getName() + "Read" + key);
        Object o = map.get(key);
        System.out.println(Thread.currentThread().getName() + "Read completed"); }}/* 1 Write 1 1 Write complete 2 Write 2 2 Write complete 3 Write 3 Write complete 4 Write 4 4 Write complete 5 Write 5 5 Write complete 1 Read 1 1 Read complete 5 Read 5 3 Read 3 3 Read complete 4 Read 4 4 Read complete 5 Read 2 2 Read complete */
Copy the code

We can see that the output is orderly when writing, and disorderly when reading. We can see that it has reached the desired effect 😊

10. Block the queue

jam

When we use blocking queues: Multi-threaded concurrent processing, thread pools!

10.1 Learn to Use queues

Add and remove elements, and now there are four sets of apis

1) the four set of apis

methods An exception is thrown No exception is thrown. There is a return value Block waiting for Timeout waiting for
add add() offer() put() offer(E e, long timeout, TimeUnit unit)
remove remove() poll() take() poll(long timeout, TimeUnit unit)
To judge the first element() peek()
/* * Throws an exception * */
    public static void test1(a){
        // Queue size 3
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
        System.out.println(blockingQueue.add("a"));
        System.out.println(blockingQueue.add("b"));
        System.out.println(blockingQueue.add("c"));
        //IllegalState ExceptionQueue Full Throws an exception
        //System.out.println(blockingQueue.add("d"));

        // Check the first element of the queue
        System.out.println(blockingQueue.element());								                                 System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        / / Java. Util. NoSuchElementException throw an exception
        //System.out.println(blockingQueue.remove());

    }
Copy the code
/* * Does not throw an exception, returns a value * */
    public static void test2(a){
        // Queue size 3
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
        System.out.println(blockingQueue.offer("a"));
        System.out.println(blockingQueue.offer("b"));
        System.out.println(blockingQueue.offer("c"));
        //false
        System.out.println(blockingQueue.offer("d"));

        // Check the first element of the queue
        System.out.println(blockingQueue.peek());
        System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        //null
        System.out.println(blockingQueue.poll());

    }
Copy the code
☞ Wait * */
    public static void test3(a) throws InterruptedException {
        // Queue size 3
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
        blockingQueue.put("a");
        blockingQueue.put("b");
        blockingQueue.put("c");
        //blockingQueue.put("d");

        // No detection queue header element
        System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
      //System.out.println(blockingQueue.take());

    }
Copy the code
/* * Wait for blocking (timeout) * */
    public static void test4(a) throws InterruptedException {
        // Queue size 3
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
        blockingQueue.offer("a");
        blockingQueue.offer("b");
        blockingQueue.offer("c");
        blockingQueue.offer("d".2, TimeUnit.SECONDS);

        // No detection queue header element
        System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        blockingQueue.poll(2,TimeUnit.SECONDS);
    }
Copy the code

SynchronizedQueue SynchronizedQueue

There’s no capacity, you have to wait for an element to come out before you can put another element in

put take

package com.zmz.queue;

/ * * *@ProjectName: Juc
 * @Package: com.zmz.queue
 * @ClassName: SyncQueue
 * @Author: Shengrui Zhang *@Date: 2021/10/8 all *@Version: 1.0 * /

import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

Unlike other lockqueues, SynchronousQueue does not store elements */
public class SyncQueue {

    public static void main(String[] args) {
        SynchronousQueue<String> synchronousQueue = new SynchronousQueue<>(); // Synchronize the queue

        new Thread(()->{

            try {
                System.out.println(Thread.currentThread().getName() + "put 1");
                synchronousQueue.put("1");
                System.out.println(Thread.currentThread().getName() + "put 2");
                synchronousQueue.put("2");
                System.out.println(Thread.currentThread().getName() + "put 3");
                synchronousQueue.put("3");
            } catch(InterruptedException e) { e.printStackTrace(); }},"Thread1").start();

        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName() + "= >" + synchronousQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName() + "= >" + synchronousQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName() + "= >" + synchronousQueue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally{}},"Thread2").start(); }}/*
Thread1put 1
Thread2=>1
Thread1put 2
Thread2=>2
Thread1put 3
Thread2=>3
*/
Copy the code

Thread pools

Thread pools have three methods, seven parameters, and four rejection policies

The operation of the program, the essence: occupy the resources of the system! Optimize CPU resource usage === => pooling technology

Thread pool, connection pool, memory pool, object pool

Pooling technology: implementation ready some resources, someone wants to use, come to me to take, after using back to me

1) Benefits of thread pools:

  1. Reduce resource consumption
  2. Improve response speed
  3. Convenient management

Thread reuse, can control the maximum number of concurrent management threads

2) Thread pools: The big three

  • ExecutorService service = Executors.newSingleThreadExecutor(); // Single thread
  • ExecutorService service = Executors.newFixedThreadPool(5); // Create a fixed thread pool size
  • ExecutorService service = Executors.newCachedThreadPool(); // Retractable,
package com.zmz.Pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/ * * *@ProjectName: Juc
 * @Package: com.zmz.ThreadPool
 * @ClassName: ThreadPool
 * @Author: Shengrui Zhang *@Date: 2021/10/8 16:44
 * @Version: 1.0 * /
public class ThreadPool {
    public static void main(String[] args) {

        ExecutorService threadPool = Executors.newSingleThreadExecutor();// Single thread
        ExecutorService threadPool2 = Executors.newFixedThreadPool(5); // Create a fixed thread pool size
        ExecutorService threadPool3 = Executors.newCachedThreadPool(); // Retractable

        // The thread pool must be closed when it runs out
        try {

            for (int i = 1; i <=100 ; i++) {
                // Create threads from a thread pool
                threadPool3.execute(()->{
                    System.out.println(Thread.currentThread().getName()+ " ok"); }); }}catch (Exception e) {
            e.printStackTrace();
        } finally{ threadPool3.shutdown(); }}}Copy the code

3) Seven parameters

public ThreadPoolExecutor(intCorePoolSize, // Core thread pool sizeintMaximumPoolSize, // The maximum thread pool sizelongKeepAliveTime, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler // reject policy) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}
Copy the code

package com.zmz.Pool;

import java.util.concurrent.*;

/ * * *@ProjectName: Juc
 * @Package: com.zmz.Pool
 * @ClassName: ThreadPoolExecutorTest
 * @Author: Shengrui Zhang *@Date: 2021/10/8 for *@Version: 1.0 * /
public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        // Get the number of CPU cores
        int max = Runtime.getRuntime().availableProcessors();
        ExecutorService service =new ThreadPoolExecutor(
                2.// Core thread pool size
                max,// Maximum thread pool size
                3.// It will be released when no one calls it
                TimeUnit.SECONDS,// Timeout unit
                new LinkedBlockingDeque<>(3),// block the queue
                Executors.defaultThreadFactory(),// The thread factory creates the thread
                new ThreadPoolExecutor.AbortPolicy()// Reject the policy
        );
        try {
            for (int i = 1; i <= 5; i++) {
                service.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "Running successfully"); }); }}catch (Exception e) {
            e.printStackTrace();
        }
        finally{ service.shutdown(); }}}Copy the code

4) Rejection strategy

  • New ThreadPoolExecutor. AbortPolicy () beyond maximum processing thread throw an exception
  • New ThreadPoolExecutor. CallerRunsPolicy () from which thread creation is carried out by the thread
  • New ThreadPoolExecutor. DiscardPolicy () the queue is full of not throw an exception
  • New ThreadPoolExecutor. DiscardOldestPolicy () try to compete with the first, also won’t throw an exception

12. Four functional interfaces

New age programmers 👨💻 : lambda expressions, chained programming, functional interfaces, Stream computing

1) Function interface

package com.zmz.FourFunction;

import java.util.function.Function;

/ * * *@ProjectName: Juc
 * @Package: com.zmz.FourFunction
 * @ClassName: functionDemo
 * @Author: Shengrui Zhang *@Date: 2021/10/8 keep *@Version: 1.0 * /
public class functionDemo {
    public static void main(String[] args) {
        Function<String, String> function = (str) -> {
            return str;
        };
        System.out.println(function.apply("Hello,zmz!")); }}Copy the code

2) Predicate interfaces

package com.zmz.FourFunction;

import java.util.function.Predicate;

/ * * *@ProjectName: Juc
 * @Package: com.zmz.FourFunction
 * @ClassName: PredicateDemo
 * @Author: Shengrui Zhang *@Date: 2021/10/8 was *@Version: 1.0 * /
public class PredicateDemo {
    public static void main(String[] args) {
        Predicate<String> predicate = (str) -> {returnstr.isEmpty(); };// false
        System.out.println(predicate.test("zmz"));
        // true
        System.out.println(predicate.test("")); }}Copy the code

3) Suppier supply interface

package com.zmz.FourFunction;

import java.util.function.Supplier;

/ * * *@ProjectName: Juc
 * @Package: com.zmz.FourFunction
 * @ClassName: SuppierDemo
 * @Author: Shengrui Zhang *@Date: 2021/10/8 time *@Version: 1.0 * /
public class SuppierDemo {
    public static void main(String[] args) {
        Supplier<String> supplier = ()->{return "1024";};
        System.out.println(supplier.get());
    }
}
Copy the code

4) Consummer interface

package com.zmz.FourFunction;

import java.util.function.Consumer;

/ * * *@ProjectName: Juc
 * @Package: com.zmz.FourFunction
 * @ClassName: ConsummerDemo
 * @Author: Shengrui Zhang *@Date: 2021/10/8 time *@Version: 1.0 * /
public class ConsummerDemo {
    public static void main(String[] args) {
        Consumer<String> consumer = (str)->{
            System.out.println(str);
        };
        consumer.accept("zmz"); }}Copy the code

Stream computing

package com.zmz.Stream;

/ * * *@ProjectName: Juc
 * @Package: com.zmz.Stream
 * @ClassName: User
 * @Author: Shengrui Zhang *@Date: 2021/10/8 18:01
 * @Version: 1.0 * /
public class User {
    private int id;
    private String name;
    private int age;

    public User(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId(a) {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge(a) {
        return age;
    }

    public void setAge(int age) {
        this.age = age; }}Copy the code
package com.zmz.Stream;

/ * * *@ProjectName: Juc
 * @Package: com.zmz.Stream
 * @ClassName: StreamDemo
 * @Author: Shengrui Zhang *@Date: 2021/10/8 18:00
 * @Version* * 1. Id must be even * * 2. Age must be greater than 23 * * 3. Change the user name to uppercase * * 4. User name in reverse order * * 5. Only one user */ is displayed

import java.util.Arrays;
import java.util.List;


public class StreamDemo {
    public static void main(String[] args) {
        User u1 = new User(1."a".23);
        User u2 = new User(2."b".23);
        User u3 = new User(3."c".23);
        User u4 = new User(6."d".24);
        User u5 = new User(4."e".25);

        List<User> list = Arrays.asList(u1, u2, u3, u4, u5);
        // lambda, chained programming, functional interfaces, streaming computing
        list.stream()
                .filter(user -> {return user.getId()%2= =0; }) .filter(user -> {return user.getAge() > 20; }) .map(user -> {returnuser.getName().toUpperCase(); }) .sorted((user1, user2) -> {returnuser2.compareTo(user1); }) .limit(1) .forEach(System.out::println); }}Copy the code

ForkJoin – Multi-line concurrent processing framework

What is ForkJoin?

Ava. Util. Concurrent. ForkJoinPool presided over by Doug Lea Java masters writing, it can be a big task into many subtasks for parallel processing, finally the subtasks results merged into the final results, and the output. This article explains the Fork/Join framework, based on the implementation of Fork/Join framework in JDK1.8+, the main source code of the Fork/Join framework is also based on JDK1.8+.

This article will try to explain the Fork/Join framework in order to enlighten you and your readers on how to design concurrent programs. This article will first explain the basic use of Fork/Join framework, and the key points need to pay attention to use; Then use the Fork/Join framework to solve some practical problems; Finally, we will explain how the Fork/Join framework works.

1) ForkJoin features: Work steal!

2) If ForkJoin is used

The first step is performed through ForkJoinPool

In the second step, execute(ForkJoinTask
task)

Third, the compute class inherits ForkJoinTask

ForkJoin compute class

ForkJoinComputer.java

package com.zmz.ForkJoin;
import java.util.concurrent.RecursiveTask;


/ * * *@ProjectName: Juc
 * @Package: com.zmz.ForkJoin
 * @ClassName: ForkJoinComputer
 * @Author: Shengrui Zhang *@Date: better 2021/10/9 *@Version: 1.0 * /

public class ForkJoinComputer extends RecursiveTask<Long> {
    private long start;
    private long end;
    /** Critical value */
    private long temp = 1000000L;

    public ForkJoinComputer(long start, long end) {
        this.start = start;
        this.end = end;
    }

    /** **@return* /
    @Override
    protected Long compute(a) {
        if ((end - start) < temp) {
            Long sum = 0L;
            for (Long i = start; i < end; i++) {
                sum += i;
            }
            return sum;
        }else {
            // Use ForkJoin to divide and conquer
            //1. Calculate the average value
            long middle = (start + end) / 2;
            ForkJoinComputer forkJoinDemo1 = new ForkJoinComputer(start, middle);
            // Split the task and push the thread into the thread queue
            forkJoinDemo1.fork();
            ForkJoinComputer forkJoinDemo2 = new ForkJoinComputer(middle, end);
            forkJoinDemo2.fork();

            long taskSum = forkJoinDemo1.join() + forkJoinDemo2.join();
            returntaskSum; }}}Copy the code

The test class ForkJoinTest. Java

package com.zmz.ForkJoin;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;

/ * * *@ProjectName: Juc
 * @Package: com.zmz.ForkJoin
 * @ClassName: ForkJoinTest
 * @Author: Shengrui Zhang *@Date: * 2021/10/9 a journey@Version: 1.0 * /
public class ForkJoinTest {
    private static final long SUM = 20 _0000_0000;

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        test1();
        test2();
        test3();
    }

    /** * use the normal method */
    public static void test1(a) {
        long star = System.currentTimeMillis();
        long sum = 0L;
        for (long i = 1; i < SUM ; i++) {
            sum += i;
        }
        long end = System.currentTimeMillis();
        System.out.println(sum);
        System.out.println("Common programming ape -- Time:" + (end - star));
        System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = =");
    }
    /** * ForkJoin is used
    public static void test2(a) throws ExecutionException, InterruptedException {
        long start = System.currentTimeMillis();

        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ForkJoinTask<Long> task = new ForkJoinComputer(0L, SUM);
        ForkJoinTask<Long> submit = forkJoinPool.submit(task);
        Long along = submit.get();

        System.out.println(along);
        long end = System.currentTimeMillis();
        System.out.println("Intermediate programming ape -- Time:" + (end - start));
        System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -");
    }
    /**
     * 使用 Stream 流计算
     */
    public static void test3(a) {
        long start = System.currentTimeMillis();

        long sum = LongStream.range(0L.20_0000_0000L).parallel().reduce(0, Long::sum);
        System.out.println(sum);
        long end = System.currentTimeMillis();
        System.out.println("Advanced Programming Ape -- Time:" + (end - start));
        System.out.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -");
        System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = ="); }}Copy the code

Analyze the advanced program ape processing:

.parallel().reduce(0, Long::sum) uses a parallel stream to compute the entire computation, improving efficiency.