Multithreading Advanced => JUC concurrent programming (has ended, but the picture is not submitted)

Multithreading Advanced => JUC concurrent programming

1. What is the JUC

Source + official documents interview HF ask!

image-20200403130707241

java.util kit, package, classification

Business: ordinary threaded code Thread

Runnable no return value, is relatively low compared to the Efficiency Callable!

image-20200403131318241

image-20200403131440493

2, threads and processes

image-20200403132053359

    public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }
	// 本地方法,底层的C++ , java  无法直接操作硬件
    private native void start0();

image-20200403132723540

image-20200403133139077

package com.kuang;

public class demo1 {
    public static void main(String[] args) {
        // 获取cpu的核数
        // CPU 密集型, IO密集型
        System.out.println(Runtime.getRuntime().availableProcessors());
    }
}

The nature of concurrent programming: full use of CPU resources

All companies are valued!

Business, money => increase efficiency, downsizing, looking for someone to replace a powerful three very good people;

Person (minus), the cost of technology (high)

2.1, there are several thread state

public enum State {
    // 新生
    NEW,
    // 运行
    RUNNABLE,
    // 阻塞
    BLOCKED,

    // 等待,死死地等
    WAITING,

    // 超时等待,等不下去了就不等
    TIMED_WAITING,

   // 终止
    TERMINATED;
}

wait / sleep difference

  • From different classes
    • wait => Object
    • sleep => Thread
  • Among enterprises, sleep, TimeUnit class
  • About the lock release
    • wait will release locks
    • sleep sleep, sleep holding the lock, the lock will not release!
  • Using a range of different
    • must wait in the synchronized block
    • sleep can sleep anywhere
  • The need to catch exceptions ( both need to catch the exception )
    • wait do not need to catch the exception
    • sleep is necessary to catch the exception

3, Lock Lock (Key)

3.1, the traditional synchronized

3.2, Lock Interface

image-20200403141203912

image-20200403141318853

image-20200403141534925

Lock fair: very fair, everyone-can

Unfair lock: very unfair, you can jump the queue (default)

package com.kuang;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SaleTicketDemo {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();

        new Thread(() -> { for (int i = 0; i < 30; i++) ticket.sale(); }, "A").start();

        new Thread(() -> { for (int i = 0; i < 30; i++) ticket.sale(); }, "B").start();

        new Thread(() -> { for (int i = 0; i < 30; i++) ticket.sale(); }, "C").start();
    }


}


class Ticket {
    private int number = 30;

    Lock lock = new ReentrantLock();

    public void sale() {

        lock.lock();
        try {
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "剩余" + (--number) + "张");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }


    }
}

3.3, synchronized and Lock difference

image-20200403150130534

4, the producer and consumer issues

Interview: Singleton, sorting algorithm, producers and consumers, the deadlock

4.1, the producer and consumer issues synchronized version

package com.kuang.pc;

public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++)
                data.increament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();

        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++)
                    data.decreament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"B").start();
    }
}

class Data{
    private int number = 0;

    public synchronized void increament() throws InterruptedException {
        if (number!=0){
            wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"==>"+number);
        notifyAll();
    }

    public synchronized void decreament() throws InterruptedException {
        if (number==0){
            wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"==>"+number);
        notifyAll();
    }
}

Problems, ABCD 4 threads! Spurious wakeup

image-20200403152635565

if 改成 while

package com.kuang.pc;

public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++)
                data.increament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();

        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++)
                    data.decreament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"B").start();

        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++)
                    data.increament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"C").start();

        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++)
                    data.decreament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"D").start();
    }
}

class Data{
    private int number = 0;

    public synchronized void increament() throws InterruptedException {
        while (number!=0){
            wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"==>"+number);
        notifyAll();
    }

    public synchronized void decreament() throws InterruptedException {
        while (number==0){
            wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"==>"+number);
        notifyAll();
    }
}

4.2, JUC version of the producer and consumer issues

image-20200403153513223

Code:

package com.kuang.pc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++)
                    data.increament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "A").start();

        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++)
                    data.decreament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "B").start();

        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++)
                    data.increament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "C").start();

        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++)
                    data.decreament();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "D").start();
    }
}

class Data {
    private int number = 0;

    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    public  void increament() throws InterruptedException {
        lock.lock();
            try {
                while (number != 0) {
                    condition.await();
                }
                number++;
            System.out.println(Thread.currentThread().getName() + "==>" + number);
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public  void decreament() throws InterruptedException {
        lock.lock();
        try {
            while (number == 0) {
                condition.await();
            }
            number--;
            System.out.println(Thread.currentThread().getName() + "==>" + number);
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

Any new technology, absolutely not just cover the original technology, there will be advantages and complement!

4.3, Condition ----- accurate notification and wake-up thread

image-20200403155837582

Test the code:

package com.kuang.pc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class A {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(() -> {
            for (int i = 0; i < 10; i++)
               data.printA();
        }, "A").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++)
                data.printB();
        }, "B").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++)
                data.printC();
        }, "C").start();

    }
}

class Data {
    private int number = 1;

    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

    public void printA() {
        lock.lock();
        try {
            while (number!=0){
                condition1.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName()+"=>AAAAAA");
            condition2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void printB() {
        lock.lock();
        try {
            while (number!=1){
                condition2.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName()+"=>BBBBBB");
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void printC() {
        lock.lock();
        try {
            while (number!=2){
                condition3.await();
            }
            number=0;
            System.out.println(Thread.currentThread().getName()+"=>CCCCCC");
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}

5,8 lock phenomenon

How to determine the object lock! Always know what is the lock, the lock in the end who is the lock?

Object, Class

6, unsafe collections

6.1, List of insecurity

image-20200403172059387

6.2, Set unsafe

image-20200403174206880

What hashSet bottom is?

image-20200403174617661

6.3, Map insecurity

Recalling the basic operation of the Map

image-20200403175113051

image-20200403175558977

7、Callable

image-20200403175811953

Callable and Runnable difference:

  • You can return a value
  • You can throw an exception
  • Different methods, call () / run ()

Test the code:

image-20200404034142764

image-20200404034257942

package com.kuang;

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

public class Test {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 适配类
        FutureTask futureTask = new FutureTask(new Callable() {
            @Override
            public Integer call() throws Exception {
                System.out.println("call()");
                return 1024;
            }
        });

        new Thread(futureTask,"A").start();
        new Thread(futureTask,"B").start(); // 结果会被缓存,效率高

        // 获取Callable返回结果并打印
        System.out.println(futureTask.get());
    }

}


detail:

  • There Cache
  • The results may have to wait, can block!

8, the auxiliary class common (must be)

8.1、CountDownLatch

image-20200404040750258

package com.kuang;

import java.util.concurrent.CountDownLatch;

// 计数器
public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        //总数是6,必须要执行任务的时候,再使用!
        CountDownLatch countDownLatch = new CountDownLatch(6);

        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"Go Out");
                countDownLatch.countDown();// 数量减一
            }, String.valueOf(i)).start();
        }

        countDownLatch.await();// 等待计数器归零,再向下执行

        System.out.println("Close Door");

    }
}

image-20200404042052553

8.2、CyclicBarrier

image-20200404042306370

Adding counter

package com.kuang;

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

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
            System.out.println("召唤神龙!");
        });

        for (int i = 1; i <= 7; i++) {
            final int temp = i;
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"收集了"+temp+"颗龙珠");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }, String.valueOf(i)).start();
        }
    }
}

8.3、Semaphore

Semaphore: Semaphore

image-20200404044938377

package com.kuang;

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

public class SemaphoreDemo {
    public static void main(String[] args) {
        //线程数量:停车位!限流!
        Semaphore semaphore = new Semaphore(3);

        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                //acquire();得到
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"抢到车位");
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println(Thread.currentThread().getName()+"离开车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }

                //release() 释放
            }, String.valueOf(i)).start();
        }
    }
}

image-20200404045129010

9, read-write locks

ReadWriteLock

image-20200404045530589

package com.kuang;

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

/**
 * 独占锁(写锁)  一次只能被一个线程占有
 * 共享锁(读锁)  多个线程可以同时占有
 */
public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyCache myCache = new MyCache();

        for (int i = 1; i <= 10; i++) {
            final int temp = i;
            new Thread(() -> {
                myCache.put(temp+"",temp+"");
            }, String.valueOf(i)).start();
        }

        for (int i = 1; i <= 10; i++) {
            final int temp = i;
            new Thread(() -> {
                myCache.get(temp+"");
            }, String.valueOf(i)).start();
        }
    }
}

class MyCache{
    private volatile Map<String,String> map = new HashMap<>();
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    public void put(String key,String value){
        readWriteLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"写入");
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"写入成功");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }

    public void get(String key){
        readWriteLock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"读取");
            map.get(key);
            System.out.println(Thread.currentThread().getName()+"读取成功");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock();
        }

    }

}

10, blocking queue

image-20200404052551832

Blocking queue:

image-20200404052720858

image-20200404053215040

BlockingQueue BlockingQueue not something new

image-20200404053536469

image-20200404053644294

image-20200404054813107

SynchronousQueue synchronous queue

image-20200404073835795

The code slightly

11, the thread pool (focus)

Thread pools: the three methods, seven parameters, four kinds deny policy

image-20200404074419948

Thread Pool: Three Methods

image-20200404074831346

package com.kuang;

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

public class Demo {
    public static void main(String[] args) {
//         Executors.newSingleThreadExecutor();
        ExecutorService threadPool = Executors.newCachedThreadPool();
//       Executors.newFixedThreadPool(3);


        try {
            for (int i = 0; i < 10; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}

Seven parameters

Source Exploration

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,//21亿
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

//本质ThreadPoolExecutor()
public ThreadPoolExecutor(int corePoolSize,//核心线程池大小
                              int maximumPoolSize,//最大核心线程池大小
                              long keepAliveTime,//超时了没有人调用就会释放
                              TimeUnit unit,//超时单位
                              BlockingQueue<Runnable> workQueue,//阻塞队列
                              ThreadFactory threadFactory,//线程工厂,创建线程的,一般不用动
                              RejectedExecutionHandler handler//拒绝策略) {
        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;
    }

image-20200404173242409

image-20200404174854707

Manually create a thread pool

package com.kuang;

import java.util.concurrent.*;

public class Demo {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2,
                5,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );


        try {
            for (int i = 0; i < 10; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}

Four kinds of rejection policy

image-20200404180345561

image-20200404180549037

Summary and expand

Learn: IO-intensive, CPU-intensive (tuning)

image-20200404181149191

package com.kuang;

import java.util.concurrent.*;

public class Demo {
    public static void main(String[] args) {

        //CPU密集型
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2,
                Runtime.getRuntime().availableProcessors(),
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );


        try {
            for (int i = 0; i < 10; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}

12, the four major functional interfaces (must master)

Programmers new era: lambda expressions, chained programming, functional interfaces, Stream flow calculation

Interface functions and only a method of an interface

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

//超级多FunctionalInterface
//简化编程模型,在新版本的框架底层大量应用!
//foreach(消费者类的函数式接口)

image-20200404191024756

image-20200404191058024

Test the code:

Function Function Interface

image-20200404192043088

image-20200404191859615

Interface has concluded an input parameters, return values ​​can only type Boolean value!

image-20200404192531770

image-20200404192640035

Consumer Consumer Interface

image-20200404193257063

image-20200404193157677

Supplier supplied Interface

image-20200404193716015

image-20200404193826242

13, Stream Flow Calculation

What is Stream-flow calculation

Big Data: Calculation storage +

Storage: collection, MySQL is the essence of what is stored

Calculation should flow to operate!

image-20200404194718084

image-20200404195115501

14, ForkJoin

What is ForkJoin

ForkJoin in JDK1.7, parallel execution of tasks! Improve efficiency. Large amount of data!

Big Data: Map Reduce (to split large tasks into small tasks)

image-20200404200009519

ForkJoin Features: work stealing

There are maintenance deque

image-20200404200300685

ForkJoin

image-20200404201058101

image-20200404201129330

image-20200404202512312

image-20200404202253924

test:

image-20200404202601159

image-20200404202357345

15, asynchronous callback

16, Jnn

image-20200404212245316

image-20200404212212103

image-20200404212521715

Thread working memory main memory

Eight kinds of operations:

image-20200404212953417

image-20200404213156605

Question: does not know the value of the main memory has been modified

image-20200404214019197

17、Volatile

Ensure visibility

image-20200404214317761

Does not guarantee atomicity

Atomicity: indivisible

A thread in the implementation of the task can not be bothered, it can not be split. At the same time either succeed or fail at the same time

image-20200404214816901

If not lock and synchronized, how to ensure atomicity

image-20200404215147457

The use of atomic class, solve the problem of atomicity

image-20200404215502779

These classes are the underlying operating system and directly linked! Modify values ​​in memory! Unsafe class is a very special presence!

Instruction reordering

What is the command rearrangement: you write a program, a computer is not as you write to execute in accordance with the.

Source code -> compiler optimization rearrangement -> Parallel instructions may rearrangement -> the memory system will rearrangement -> execution

image-20200405210100223

image-20200405210719492

image-20200405210811611

18, completely Fun singleton

Starving type DCL lazy type, explore!

Hungry Chinese-style

image-20200405213715042

DCL lazy style

image-20200405215329797

Static inner classes

image-20200405215428090

Single cases unsafe, reflecting

enumerate

image-20200405215608827

image-20200405215736775

Enumerated type of final anti-compile the code:

image-20200405220003880

19 in-depth understanding of CAS

What is CAS

You have to be giant-depth study of the bottom! A breakthrough! Repair the internal strength, operating system, computer network theory

image-20200405222323983

Unsafe class

image-20200405221657703

image-20200405222149961

image-20200405222228837

CAS: comparing the current value of the value of working memory and main memory, if this value is desired, then the action is performed! If not, have been circulating!

Disadvantages:

  • The cycle time-consuming
  • Disposable can only guarantee the atomicity of a shared variable
  • ABA problem exists

CAS of the ABA problem (狸猫换太子)

image-20200405223439827

image-20200405223633888

20, atom quote

ABA solve the problem, the introduction of atomic references! Corresponding thought: optimistic locking!

Versioned atomic operation!

image-20200405225302311

note:

image-20200405224930224

21, all kinds of locks understand

Fair locks, lock unfair

Unfair lock: very unfair, you can jump the queue (default is unfair)

Reentrant lock

Reentrant lock (lock recursion)

image-20200405230157725

synchronized version (Code omitted)

lock version (Code omitted)

Spinlocks

spinlock

image-20200405230804001

Custom lock

image-20200405232051150

test:

image-20200405232225759

image-20200405232319119

Deadlock

What is a deadlock?

image-20200405232524059

Deadlock test, how to exclude deadlock:

image-20200405233140645

Solve the problem:

image-20200405233506797

image-20200405233559298

Interview, work! Troubleshooting:

  • Log 9 people (leaders do not like, do not like the operation and maintenance)
  • Stack 1 person (like leadership, do not bother this method of operation and maintenance)

Guess you like

Origin www.cnblogs.com/ilbty/p/12640015.html