多线程(进阶)

1、基础

 

2、线程和进程:

多线程(进阶)

 

多线程(进阶)

 

1.线程六个状态:

多线程(进阶)

 

还有一个"终止"

2.wait和sleep的区别:

多线程(进阶)

 

 

3、Lock锁(重点)

传统 Synchronized:

不公平锁

Lock接口:

多线程(进阶)

 

公平锁:十分公平:可以先来后到非公平锁:十分不公平:可以插队 (默认)

 

Synchronized 和 Lock 区别:

1、 Synchronized 内置的Java关键字, Lock 是一个Java类

2、 Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁

3、 Synchronized 会自动释放锁,lock 必须要手动释放锁!如果不释放锁,死锁

4、 Synchronized 线程 1(获得锁,阻塞)、线程2(等待,傻傻的等);Lock锁就不一定会等待下去;

5、 Synchronized 可重入锁,不可以中断的,非公平;Lock ,可重入锁,可以 判断锁,非公平(可以自己设置);

6、 Synchronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码!

 

4、生产者和消费者问题

多线程(进阶)

 

面试的:单例模式、排序算法、生产者和消费者、死锁

生产者和消费者问题 Synchronized 版

解决if用While

 

5.lock与Synchronized对应的方法:

多线程(进阶)

 

Synchronized:

多线程(进阶)

 

(重):

  • 多个线程用同一个对像,调用同一个类被Synchronized锁的方法,变量,线程都只能一个一个来调用!
  • 多个线程如果用的是不同对像(不同的类),调用被Synchronized锁的方法,变量,线程不相干扰!

static修饰的概念是类的模板,任何类还没加载就要先加载类它的模板,类的模板只有一个。

如果被static(静态修饰),就算用不同的对象(名字)声明,static修饰的都是指向它唯一的类模板,只能一个一个调用

 

6、Condition的使用

lockd等待,唤醒方法:多线程(进阶)

condition1.signal();唤醒condition1

Lock-精准唤醒:

多线程(进阶)

 

 

 

7、List的安全

List<String> list = new CopyOnwriteArrayList<>();

多线程(进阶)

 

 

 

8、Set的安全

Set<string> set = new CopyOnwriteArrayset<>();

多线程(进阶)

 

 

9、map的安全

Collections.synchronizedMap(Map<K,V> m) )可以代替HashMap,但是它们都是通过使用一个全局的锁来同步不同线程间的并发访问,因此会带来不可忽视的性能问题。

Map<string, string> map = new ConcurrentHashMap<>();

多线程(进阶)

 

ConcurrentHashMap是J.U.C(java.util.concurrent包)的重要成员,它是HashMap的一个线程安全的、支持高效并发的版本。在默认理想状态下,ConcurrentHashMap可以支持16个线程执行并发写操作及任意数量线程的读操作。本文将结合Java内存模型,分析JDK源代码,探索ConcurrentHashMap高并发的具体实现机制,包括其在JDK中的定义和结构、并发存取、重哈希和跨段操作,并着重剖析了ConcurrentHashMap读操作不需要加锁和分段锁机制的内在奥秘和原理。

 

 

11、常用辅助类

CountDownLatch

线程减法计数器

多线程(进阶)

 

多线程(进阶)

 

 

CyclicBarrier

线程加法计数器

多线程(进阶)

 

多线程(进阶)

 

 

Semaphore

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

 

12、读写锁

多线程(进阶)

 

使用

多线程(进阶)

 

没有加锁时:

多线程(进阶)

 

结果

多线程(进阶)

 

读锁和写锁

又名(独占锁和共享锁)

多线程(进阶)

 

结果

多线程(进阶)

 

总结

多线程(进阶)

 

 

13、阻塞队列

队列和阻塞

多线程(进阶)

 

多线程(进阶)

 

BlockingQueue

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

1、抛出异常:

多线程(进阶)

 

多线程(进阶)

 

 

2、返回Boolean值

多线程(进阶)

 

多线程(进阶)

 

 

3、一直阻塞

多线程(进阶)

 

多线程(进阶)

 

 

4、超时等待

多线程(进阶)

 

 

14、同步队列

SynchronousQueue

BlockingQueue<String> blockingQueue = new SynchronousQueue<>(); //同步队列

多线程(进阶)

 

多线程(进阶)

 

结果:

多线程(进阶)

 

总结

多线程(进阶)

 

 

15、线程池

Executors线程池

Executors线程池三大方法

1、单个线程池

多线程(进阶)

 

 

2、固定线程池

多线程(进阶)

 

 

3、可伸缩线程池

多线程(进阶)

 

三大方法本质

多线程(进阶)

 

 

ThreadPoolExecutor

1、阿里巴巴规范手册说明

多线程(进阶)

 

2、ThreadPoolExecutor七大参数

多线程(进阶)

 

多线程(进阶)

 

 

2、ThreadPoolExecutor四种拒接策略

多线程(进阶)

 

1、

多线程(进阶)

 

2、

多线程(进阶)

 

3、

多线程(进阶)

 

4、

多线程(进阶)

 

 

池大小设置优化

多线程(进阶)

 

1、CPU密集型

多线程(进阶)

 

2、IO密集型

多线程(进阶)

 

 

 

16、四大函数式接口

多线程(进阶)

 

 

1、Function函数式接口

多线程(进阶)

 

还能把括号去掉

多线程(进阶)

 

2、断定型接口

多线程(进阶)

 

多线程(进阶)

 

 

 

3、Consumer消费型接口

多线程(进阶)

 

多线程(进阶)

 

 

4、 Supplier供给型接口

多线程(进阶)

 

多线程(进阶)

 

 

17、Stream流式计算(1.8新特性)多线程(进阶)

 

 

18、ForkJoin

多线程(进阶)

 

1、ForkJoin的特点:工作窃取

双端队列

多线程(进阶)

 

2、使用和对比

多线程(进阶)

 

使用三种方法计算1+到10亿的值

1、普通For循环

多线程(进阶)

 

 

2、ForkJoin

2.1、编写计算类

多线程(进阶)

 

多线程(进阶)

 

2.2、创建ForkJoin工厂执行计算

多线程(进阶)

 

 

3、Stream流式计算

一行代码

多线程(进阶)

 

4、结果

多线程(进阶)

 

 

19、异步回调

CompletableFuture

1、没有返回值()

多线程(进阶)

 

 

2、有返回结果(supplyAsync)

多线程(进阶)

 

 

20、JMM

多线程(进阶)

 

 

多线程(进阶)

 

 

多线程(进阶)

 

JMM的八种指令

多线程(进阶)

 

多线程(进阶)

 

 

21、Volatile

1、保持可见性

缓存锁:

总线加锁

缓存一致性协议

2、不保证原子性

多线程(进阶)

 

如:多线程调用num++;

多线程(进阶)

 

除了加锁lock和synchronized还有原子类可以保证原子性

原子类CAS

多线程(进阶)

 

实现多线程(进阶)

多线程(进阶)

 

多线程(进阶)

 

 

3、避免指令重排

多线程(进阶)

 

多线程(进阶)

 

Volatile的实现

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

(2)禁止指令重排底层原理:
volatile实现禁止指令重排优化,从而避免多线程环境下程序出现乱序执行的现象。

 

先了解下概念,内存屏障(Memory Barrier)又称内存栅栏,是一个CPU指令,它的作用有两个:

保证特定操作执行的顺序性;
保证某些变量的内存可见性(利用该特性实现volatile内存可见性)

volatile实现禁止指令重排优化底层原理:

由于编译器和处理器都能执行指令重排优化。如果在指令间插入一条Memory Barrier则会告诉编译器和CPU,不管什么指令都不能和这条Memory Barrier指令重排,也就是说通过插入内存屏障,就能禁止在内存屏障前后的指令执行重排优化。内存屏障另外一个作用就是强制刷出各种CPU的缓存数据,因此任何CPU上的线程都能读取到这些数据的最新版本。

左边:写操作场景:先LoadStore指令,后LoadLoad指令。

右边:读操作场景:先LoadLoad指令,后LoadStore指令。

多线程(进阶)

 

 

 

22、单例模式

概念:

java中单例模式是一种常见的设计模式,单例模式的写法有很多种,比较常见的有三种:懒汉式、饿汉式、内部类、双重验证。
单例模式有以下特点:
1、单例类只能有一个实例(new 的对象)。
2、单例类必须自己创建自己的唯一实例。

3、单例类必须给所有其他对象提供这一实例。

 

单例模式确保该类只被是实例化一次,并且只能自己实例化自己。

若想某一类不在类外被实例化,只需用private修饰符修饰其构造函数。

1、饿汉式

多线程(进阶)

 

2、懒汉式

多线程(进阶)

 

多线程(进阶)

 

3、静态内部类式

多线程(进阶)

 

 

23、深入理解CAS

多线程(进阶)

 

AtomicInteger

 

1、Unsafe类

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

 

ABA问题

多线程(进阶)

 

多线程(进阶)

 

通俗来讲就是你大爷还是你大爷,你大妈已经不是你大妈了^_^(他已经被动过了)

代码实现

多线程(进阶)

 

解决办法

如果线程one操作不被中断,那么问题就解决了

  • 将类变成原子类
  • 操作过程添加版本号

即为下面的原子引用!

 

24、原子引用

AtomicStampedReference

多线程(进阶)

 

但是Integer类型的范围是-128~127,超出范围会在堆里面新建一个对象并不会复用对象

你自己看一下源码compareAndSet源码,底层是用==进行判断

带版本号的原子类

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

它被人动过,版本号就不是原来的版本号了

 

25、各种锁的理解

1、公平锁和非公平锁

多线程(进阶)

 

2、可重入锁

(递归锁)

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

可重入锁是指:某个线程已经获取了某个锁,那么他可以再次获取该锁而不陷入死锁

总结下:什么是 "可重入",可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。

 

3、自旋锁

多线程(进阶)

 

多线程(进阶)

 

 

4、死锁

多线程(进阶)

 

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

解开死锁,避免死锁产生的条件就可以了

 

26、ThreadLocal的原理和使用场景

多线程(进阶)

 

多线程(进阶)

 

区别:

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

多线程(进阶)

 

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

 

多线程(进阶)

 

多线程(进阶)

 

多线程(进阶)

 

 

 

 

 

 

 

 

 

 

 

 

1

1

1

1

1

1

1

1

1

1

1

1

 

 

 

 

 

 

 

 

 

 

多线程(进阶)

上一篇:详解python解包


下一篇:五十四、Python里面Jenkins自动执行py文件