线程池
池化技术
提前准备好资源,在需要用的时候,重复利用这些预选准备的资源
提前创建,重复使用
在java创建时一般有这几个步骤
1 根据new标识后面的参数去产量池查找类的符号引用
2 如果没有找到,再对类进行,加载,连接,初始化
3 虚拟机在堆中为对象分配内存,针对对象头,建立起对应的数据结构(耗时操作,需要寻找空闲区域,修改内存分配状态)
4 调用对象初始化方法(用户的复杂逻辑操作耗时)
所以说创建一个类需要历经复杂繁琐的操作,然后池化技术可以提前创建类,并重复利用。
三大方法
01:Executors.newSingleThreadExecutor() //单个线程
02:newFixedThreadPool(int nThreads) //创建一个固定的线程池的大小
03:newCachedThreadPool() //缓存池,可伸缩的, 遇强则强,遇弱则弱
七大参数
拒绝策略
package com.boom.example.demo.aa;
import java.util.concurrent.*;
public class ExecutorDemo {
public static void main(String[] args) {
ExecutorService executorService = new ThreadPoolExecutor(
2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
try {
for(int i=1;i<=8;i++)
{
executorService.execute(() -> {
System.out.println(Thread.currentThread().getName() + "ok");
});
}
} catch (Exception e) {
e.printStackTrace();
}finally {
executorService.shutdown();
}
}
}
CPU密集型和I/O密集型
CUP密集型也叫计算机密集型,进程的绝大数时间花在计算上,比如一些循环代码(图片处理,视频编码,人工智能)计算CUP密集型
进程绝大部分时间花在Input和Output上,称为I/O密集型,比如搜索引擎蜘蛛大多数时间是在等待相应I/O就是属于I/O密集型
计算机密集主要消耗CUP资源,所以代码的运行效率至关重要,像Python这种脚本语言运行效率很低,完全不适合计算机密集任务,对于计算机密集任务,最好用C语言编写,对于IO密集型任务,最合适的语言就是开发效率最高(代码量最少)的语言,脚本语言是首选,C语言最差。总之,计算密集型程序适合C语言多线程,I/O密集型适合脚本语言开发的多线程。
四大函数式接口
Stream流计算
package com.boom.example.demo.cc;
import org.w3c.dom.ls.LSOutput;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class StreamDemo {
public static void main(String[] args) {
User u1 = new User(1, "a", 21);
User u2 = new User(2, "b", 22);
User u3 = new User(3, "c", 23);
User u4 = new User(4, "d", 24);
User u5 = new User(6, "e", 25);
List<User> users = Arrays.asList(u1, u2, u3, u4, u5);
users.stream().filter( u -> {return u.getId()%2 == 0;})
.filter(u -> {
return u.getAge() > 23;
})
.map(u ->{return u.getName().toUpperCase();})
.sorted((uu1,uu2)->{return uu1.compareTo(uu2);})
.forEach(System.out::println);
}
}
JMM
Java内存模型规定了所有的变量都存储在主内存(Main Memory)中。每条线程还有自己的工作内存(Working Memory,可与前面讲的处理器高速缓存类比),线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成,线程、主内存、工作内存三者的交互关系如图所示。
volatile
保证可见性
不保证原子性
禁止指令重排
原子性(Atomicity):一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
可见性(Visibility):可见性是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。
CAS
CAS是英文单词CompareAndSwap的缩写,中文意思是:比较并替换。CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B。
CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。