JUC
进程和线程
进程:一个程序,QQ,微信,
一个进程至少包含一个线程,可以有多个线程
java默认有2个线程。main线程和GC线程
线程:
Java: Thread Runable Callable
java无法直接开启线程,是用的本地方法开启的。
并发和并行
并发:多个线程操作同一个资源。单核CPU
并行:多个人一起行走。多个CPU
并发编程的的本质:充分利用CPU的资源
线程
线程的状态
新生、运行、阻塞、等待(死等)、超时等待、终止
wait和sleep的区别
1.来自不同的类,Object.wait Thread.sleep
<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n25" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit; background-repeat: inherit;">TimeUnit.SECONDS.sleep(1000);//睡1000秒</pre>
2.关于锁的释放
wait会释放锁
sleep抱着锁睡觉,不会释放锁
3.使用的范围是不同的
wait只能在同步代码块中使用
sleep可以在任何地方使用
4.是否需要唤醒
wait需要被唤醒 notify
sleep到时自动唤醒
Lock
传统Synchronize
synchronize 本质:队列,锁
Lock接口
三个实现类:
ReentrantLock 普通可重入锁
ReentrantReadWriteLock.ReadLock 读锁
ReentrantReadWriteLock.writeLock 写锁
<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n51" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit; background-repeat: inherit;">Lock lock = new ReentrantLock();默认是非公平锁
Lock lock = new ReentrantLock(true);公平锁</pre>
公平锁:十分公平,排队获取锁
为什么默认不是公平锁。如果两个任务 一个3h,一个3s。3s排在3h后面的话就要等3小时才能获取到锁。
非公平锁:可以插队,synchronize也是非公平锁
Lock和synchronize的区别
1.synchronize是一个关键字,Lock是一个接口
2.synchronize无法获取到锁状态,Lock可以判断是否获取到了锁
3.synchronize是全自动的,会自动释放锁。Lock需要手动解锁
4.synchronize 线程1获得锁之后线程2会一直等待;Lock不一定会等待下去。tryLock
5.synchronize 可重入,非公平,不可中断;Lock 可重入锁,可以自己设置公平不公平,可以判断锁
6.synchronize 适合锁少量的代码块,Lock适合锁大量的代码块
锁是什么,如何判断锁是谁的?
<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n65" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit; background-repeat: inherit;">这里的synchronized锁的是调用该方法的对象
pubicl void synchronized test(){
...
}
这里的synchronized锁锁的是当前类
pubicl static void synchronized test(){
...
}
</pre>
集合
对集合并发操作,会出现ConcurrentModificationException 并发修改异常
List
<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n70" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit; background-repeat: inherit;">解决并发修改异常的方法
- 1. Collections.synchronizedList() -- synchronized (mutex) {list.add(index, element);}
- 2. new CopyOnWriteArrayList<>();-- 用的lock锁,写时复制,每次新增一个元素时,直接复制以前的元素到新的一个list
- 3.new Vector<>(); 最早出现jdk1.0 直接锁整个方法,效率差</pre>
Set
<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n72" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit; background-repeat: inherit;">Collections.synchronizedSet(new HashSet<>());</pre>
HashSet
<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n74" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit; background-repeat: inherit;">实际上就是一个hashmap
public HashSet() {
map = new HashMap<>();
}
add方法就是put一个key。value是固定的
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}</pre>
Map
<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n76" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit; background-repeat: inherit;">Collections.synchronizedMap(new HashMap<>());
new ConcurrentHashMap<>(); //推荐使用
new Hashtable<>();</pre>
callable
callable特点
1.有缓存
2.通过futuretask.get()阻塞,并获取结果
<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n82" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit; background-repeat: inherit;">public class CallableTest {
public static void main(String[] args) throws Exception{
FutureTask futureTask = new FutureTask(()->{
System.out.println(123);
return "123";
});
new Thread(futureTask,"A").start();
new Thread(futureTask,"B").start(); //只会打印一遍123,取得是缓存
futureTask.get();
}
}
class MyThread implements Callable<String>{
@Override
public String call() throws Exception {
return "123";
}
}</pre>
读写锁
队列
[图片上传失败...(image-bf7888-1642649477663)]
启动多少个线程
CPU密集型和IO密集型
CPU密集型:根据CPU核心数来,跟CPU核心数保持一致最好
IO密集型:设置2倍io任务数
四大函数式接口
Lamab 链式编程 函数式接口 stream流式计算
函数式接口:只有一个方法的接口 ,只要是函数式接口就可以用lamab简化,实际上是匿名内部类
<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n102" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit; background-repeat: inherit;">@FunctionalInterface
public interface Runnable {
public abstract void run();
}
foreach()//需要一个consumer函数式接口参数</pre>
[图片上传失败...(image-904e85-1642649477663)]
函数型Function 传入一个参数T返回一个类型R
断定型 传入一个参数,返回一个boolean
消费型Consumer 传入一个参数,没有返回值
供给型Supplier 没有参数,返回一个对象
Stream流式计算