Multithreading Advanced => JUC concurrent programming
1. What is the JUC
Source + official documents interview HF ask!
java.util kit, package, classification
Business: ordinary threaded code Thread
Runnable no return value, is relatively low compared to the Efficiency Callable!
2, threads and processes
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();
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
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
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
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
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
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
6.2, Set unsafe
What hashSet bottom is?
6.3, Map insecurity
Recalling the basic operation of the Map
7、Callable
Callable and Runnable difference:
- You can return a value
- You can throw an exception
- Different methods, call () / run ()
Test the code:
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
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");
}
}
8.2、CyclicBarrier
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
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();
}
}
}
9, read-write locks
ReadWriteLock
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
Blocking queue:
BlockingQueue BlockingQueue not something new
SynchronousQueue synchronous queue
The code slightly
11, the thread pool (focus)
Thread pools: the three methods, seven parameters, four kinds deny policy
Thread Pool: Three Methods
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;
}
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
Summary and expand
Learn: IO-intensive, CPU-intensive (tuning)
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(消费者类的函数式接口)
Test the code:
Function Function Interface
Interface has concluded an input parameters, return values can only type Boolean value!
Consumer Consumer Interface
Supplier supplied Interface
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!
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)
ForkJoin Features: work stealing
There are maintenance deque
ForkJoin
test:
15, asynchronous callback
16, Jnn
Thread working memory main memory
Eight kinds of operations:
Question: does not know the value of the main memory has been modified
17、Volatile
Ensure visibility
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
If not lock and synchronized, how to ensure atomicity
The use of atomic class, solve the problem of atomicity
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
18, completely Fun singleton
Starving type DCL lazy type, explore!
Hungry Chinese-style
DCL lazy style
Static inner classes
Single cases unsafe, reflecting
enumerate
Enumerated type of final anti-compile the code:
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
Unsafe class
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 (狸猫换太子)
20, atom quote
ABA solve the problem, the introduction of atomic references! Corresponding thought: optimistic locking!
Versioned atomic operation!
note:
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)
synchronized version (Code omitted)
lock version (Code omitted)
Spinlocks
spinlock
Custom lock
test:
Deadlock
What is a deadlock?
Deadlock test, how to exclude deadlock:
Solve the problem:
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)