Lambda表达式(二)
1、如何使用 lambda表达式1.1 lambda语法12// 格式遵循: (接口参数)->表达式(具体实现的方法)(paramters) -> expression 或 (parameters) ->{ expressions; } 具体解释,如上图。此外,lambda 语法注意点: 可选类型声明:方法参数不需要声明参数类型,编译器可以统一识别参数值。 可选的参数圆括号:一个参数无需定义圆括号,但无参数或多个参数需要定义圆括号。 可选的大括号:如果具体实现方法只有一个语句,就不需要使用中括号{}。 可选的返回关键字:如果具体实现方法只有一个表达式,则编译器会自动返回值,如果有多个表达式则,中括号需要指定明表达式返回了一个数值。 具体使用示例: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455public class Example { //...
JUC(七)
1、锁1.1、公平锁与非公平锁 公平fair锁:遵守FIFS,先来先服务,按照线程的申请顺序 非公平Nofair:多个线程获取锁的顺序不是严格按照申请的顺序,存在插队现象,在高并发的环境下,可能造成优先级反转或者饥饿现象,synchronized是一种非公平锁 1234public ReentrantLock() { // 默认非公平锁 sync = new...
JUC(六)
1、CPU密集型任务该任务需要大量的运算,没有阻塞,CPU一直全速运行。CPU密集任务只有在多核CPU上才可能通过多线程得到加速。CPU密集型任务配置尽可能少的线程数量,线程池大小的一般公式:CPU核数+1个线程 比如像加解密,压缩、计算等一系列需要大量耗费 CPU 资源的任务,大部分场景下都是纯 CPU 计算 对于 CPU 密集型计算,多线程本质上是提升多核 CPU 的利用率,所以对于一个 8 核的 CPU,每个核一个线程,理论上创建 8 个线程就可以了。 如果设置过多的线程数,实际上并不会起到很好的效果。此时假设我们设置的线程数量是 CPU 核心数的 2 倍,因为计算任务非常重,会占用大量的 CPU 资源,所以这时 CPU 的每个核心工作基本都是满负荷的, 而我们又设置了过多的线程,每个线程都想去利用 CPU 资源来执行自己的任务,这就会造成不必要的上下文切换,此时线程数的增多并没有让性能提升,反而由于线程数量过多会导致性能下降。 因此,对于 CPU 密集型的计算场景,理论上线程的数量 = CPU 核数就是最合适的,不过通常把线程的数量设置为CPU 核数...
JUC(五)
1、线程池的工作原理我们在工作中或多或少都使用过线程池。但是为什么要使用线程池呢?从它的名称中我们就可以猜到,线程池是使用了一种池化技术(Pooling Technology)。和很多其他池化技术一样,都是为了更高效的利用资源,例如连接池,内存池等。 数据库连接是一种很昂贵的资源,创建和销毁都需要付出高昂的代价。为了避免频繁地创建数据库连接,所以产生了数据库连接池技术。优先在池子中创建一批数据库连接,当有需要访问数据库时,直接到池子中去获取一个可用的连接,使用完了之后再归还到连接池中去。 同样的,线程也是一种很宝贵的资源,并且也是一种有限的资源,创建和销毁线程也同样需要付出不菲的代价。我们所有的代码执行都是由一个一个的线程支撑起来的,如今的芯片架构也决定了我们必须编写多线程执行的程序,以获得最高的程序性能。那么怎样高效地管理多线程之间的分工与协作就成了一个关键问题,Doug...
JUC(一)
J(java)U(util)C(concurrent)其实就是指上图的三个包。 1、Volatitlejvm提供的轻量级同步机制,它有三个特征 保证可见性 禁止指令重排 不保证原子性 JMM(Java Memory...
JUC(三)
...
JUC(二)
1、CAS1.1、概述 结合JMM线程的工作内存,主内存,副本之类的知识点。CAS主要对副本写回主内存进行了限定要求。主存有一个变量为num,其值为5,称之为A,A指代主存num的值Thread1从主内存拷贝副本到自己的工作内存,此时的副本称之为B,B指代副本num = 5Thread1将num修改为2019,此时称之为C,C指代副本num = 2019Thread1将修改过的num写回主内存时,做如下事情:将B与A进行比较,如果相等,说明在我Thread1一顿猛操作的期间,没有第二个线程动过num,所以我Thread1可以大胆的将新num,也就是C,写回内存; 如果不相等,说明在我Thread1操作期间,有人先我一步动过了num,把它给改变了,那我之前的一顿操作都是在旧数据的基础上干的,其实就是白干了,所以无法写回内存。 1234567891011121314151617181920public static void demo1() { // 主内存的值 AtomicInteger atomicInteger = new...
JUC(四)
在学习面向对象OOP时,肯定听过一句话,java皆对象,要什么对象就new什么对象。之后学习spring时,发现通过DI依赖注入后,便不再手动new对象了。同理,在之前javase学习Thread时,手动new...
限流算法
限流是解决高并发大流量的一种方案,至少是可以保证应用的可用性。 通常有以下两种限流方案: 漏桶算法 令牌桶算法 漏桶算法 漏桶算法非常简单,就是将流量放入桶中并按照一定的速率流出。如果流量过大时候并不会提高流出效率,而溢出的流量也只能是抛弃掉了。 这种算法很简单,但也非常粗暴,无法应对突发的大流量。 这时可以考虑令牌桶算法。 漏桶算法 令牌桶算法是按照恒定的速率向桶中放入令牌,每当请求经过时则消耗一个或多个令牌。当桶中的令牌为 0 时,请求则会被阻塞。 令牌桶算法支持先消费后付款,比如一个请求可以获取多个甚至全部的令牌,但是需要后面的请求付费。也就是说后面的请求需要等到桶中的令牌补齐之后才能继续获取。 12345678910111213141516171819202122232425@Override public BaseResponse<UserResVO> getUserByFeignBatch(@RequestBody UserReqVO userReqVO) { //调用远程服务 ...
线程和进程的区别
...