JUC初步理解(三)

线程池

池化技术

提前准备好资源,在需要用的时候,重复利用这些预选准备的资源
提前创建,重复使用

在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,否则就什么都不做。整个比较并替换的操作是一个原子操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值