JUC并发编程

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流式计算

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容