线程池

线程池

池化技术

程序运行,本质:占用系统的资源!优化资源的使用=》池化技术

池化技术:事先准备好一些资源,有人用,就来拿,用完返回池

线程池的好处:

1、降低资源的消耗

2、提供响应的速度

3、方便管理

线程服用、可以控制最大并发数、管理线程

线程池:三大方法、7大参数、4种拒绝策略

三大方法

//使用线程池要用线程池创建线程
public class Demo1 {
    public static void main(String[] args) {
//        ExecutorService threadPool = Executors.newSingleThreadExecutor();//单个线程
//        ExecutorService threadPool = Executors.newFixedThreadPool(5);//创建一个固定的线程池大小
        ExecutorService threadPool = Executors.newCachedThreadPool();//可伸缩的

        try {
            for (int i = 0; i < 100; i++) {
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName() + "ok");
                });

            }
            //线程池用完需要结束线程池
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPool.shutdown();
        }

    }
}

最好不要通过Executors创建线程池,而是通过ThreadPoolExecutor的方式创建,避免内存泄漏

最大 线程为21亿线程

@Native public static final int   MAX_VALUE = 0x7fffffff;

7大参数

public ThreadPoolExecutor(int corePoolSize, //核心线程池大小
                          int maximumPoolSize,//最大核心线程池大小
                          long keepAliveTime,//超时时间(没有人调用释放)
                          TimeUnit unit,//超时单位
                          BlockingQueue<Runnable> workQueue,//阻塞队列
                          ThreadFactory threadFactory) {//线程工厂,创建线程用的,一般不用动
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         threadFactory, defaultHandler);//defaultHandler拒绝策略
}

4种拒绝策略

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WNZuNrGO-1617319742111)(C:\Users\zyq zt\AppData\Roaming\Typora\typora-user-images\image-20210401215516907.png)]

public class Demo2 {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
                5,
                3,
                TimeUnit.SECONDS, new LinkedBlockingQueue<>(4),
//                new ThreadPoolExecutor.CallerRunsPolicy(),
//                new ThreadPoolExecutor.DiscardOldestPolicy(),
                new ThreadPoolExecutor.DiscardPolicy());
        //默认AbortPolicy拒绝策略 超过队列抛出异常容量为::最大核心线程池大小+阻塞队列数
        //CallerRunsPolicy 哪里来的回哪里去
        //ThreadPoolExecutor.DiscardPolicy() 队列满了不抛出异常
        //ThreadPoolExecutor.DiscardOldestPolicy() 队列满了抛弃最老的

        try {
            for (int i = 1; i <= 10; i++) {
                threadPoolExecutor.execute(()->{
                    System.out.println(Thread.currentThread().getName()+" ok");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPoolExecutor.shutdown();
        }
    }
}

最大线程如何定义

(调优方式)

CPU密集型:几核就是可以定义多少个线程

IO密集型:判断你程序十分耗IO的线程,如果是15个,设置30个

四大函数式接口

lambda表达式

链式编程

函数式接口

Stream流计算

函数式接口

只有一个函数的接口,简化编程模型,在新版本的框架底层大量运用

        List list = new ArrayList();
	    list.forEach();//函数式接口
public static void main(String[] args) {
    //    Function<T,R> //传入参数T,返回参数R
    
    Function<String,Integer> function = (a) -> {return 2;};
    System.out.println(function.apply("1"));

    //断定型接口
    Predicate<String> predicate = (str)->{ return str.isEmpty();};
    System.out.println(predicate.test("aaa"));

    //

}

    public static void main(String[] args) {
        //Consumer只有输入没有返回
        Consumer<String> consumer = (str) -> System.out.println(str);
        consumer.accept("aaa");

        //Supplier值返回不输入
        Supplier<String> supplier = () -> {return "aaa1";};
        System.out.println(supplier.get());
    }

流式计算

public class Test {
    //链式编程
    public static void main(String[] args) {
        User u1 = new User(1,"zzz",21);
        User u2 = new User(2,"www",22);
        User u3 = new User(3,"yyy",23);
        User u4 = new User(4,"ddd",24);
        User u5 = new User(5,"sss",25);
        List<User> list = Arrays.asList(u1, u2, u3, u4, u5);
        Arrays.asList(u1,u2,u3,u4,u5).stream()
                .filter(p -> p.getId()%2==0).forEach(System.out::println);

        list.stream().map( u -> u.getName().toUpperCase(Locale.ROOT)).forEach(System.out::println);
    }
}

ForkJoin

并行执行任务,提高效率

分而治之

特点:工作窃取====》原理双端队列

异步回调、

//异步调用ajax
//异步执行
//成功回调
public class Demo01 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //

        CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(()->{
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "runAsync=>void");
        });
        System.out.println("==============");
        completableFuture.get(); //获取阻塞执行结果


        //有返回值的异步回调
        CompletableFuture<Integer> completableFuture1 = CompletableFuture.supplyAsync(()->{
            return 11;
        });
        System.out.println(completableFuture1.whenComplete((t, u) -> {
            System.out.println(t);//正常返回结果
            System.out.println(u);//错误信息
        }).exceptionally((t) -> {
            System.out.println(t.getMessage());
            return 1;
        }).get());
    }
}

JMM

Volatiler:是java虚拟机提供轻量级的同步机制

保证可见性:怎么保证可见性—需要了解JMM

不保证原子性

禁止指令重排

关于JMM的一些同步的约定:

  • 线程解锁前,必须把共享变量立刻刷新回主存
  • 线程加锁前,必须读取主存中的最新值到工作内存中
  • 加锁和解锁是同一把锁

线程分为 工作内存、主内存

8种操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-axmb9B9N-1617319742113)(C:\Users\zyq zt\AppData\Roaming\Typora\typora-user-images\image-20210402071025816.png)]

(1)lock(锁定):作用于 主内存的变量,把一个变量标记为一条线程独占状态

(2)unlock(解锁):作用于 主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定

(3)read(读取):作用于 主内存的变量,把一个变量值从主内存传输到线程的 工作内存中,以便随后的load动作使用

(4)load(载入):作用于 工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中

(5)use(使用):作用于 工作内存的变量,把工作内存中的一个变量值传递给执行引擎

(6)assign(赋值):作用于 工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量

(7)store(存储):作用于 工作内存的变量,把工作内存中的一个变量的值传送到 主内存中,以便随后的write的操作

(8)write(写入):作用于 工作内存的变量,它把store操作从工作内存中的一个变量的值传送到 主内存的变量中

保证可见性

public class JMMDemo {
    //不加volatile会死循环
    //volatile可以保证可见性
    private volatile static int num = 0; 
    public static void main(String[] args) {

        new Thread(()->{
            while (num ==0){ //线程不知道内存种num值已经被修改了,会一直循环

            }
        }).start();
        try {
            TimeUnit.SECONDS.sleep(1);
        }catch (InterruptedException e){

        }
        num = 1;
        System.out.println(num);
    }
}

不保证原子性

线程A执行任务的时候,不能被打扰,要么同时成功,要么同时失败

public class VDemo2 {
    //volatile 不保证原子性 可通过lock和sychronized保证原子性
    //不用锁如果保证原子性 num++不保证原子性
    //可以使用原子类,处理原子问题(效率比锁高)
    private volatile static AtomicInteger num = new AtomicInteger();
    public static void add(){
//        num ++;
        num.getAndIncrement();
    }

    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    add();
                }
            }).start();

        }
        while (Thread.activeCount()>2) {
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + "" + num);
    }

}

{
new Thread(()->{
for (int j = 0; j < 1000; j++) {
add();
}
}).start();

    }
    while (Thread.activeCount()>2) {
        Thread.yield();
    }
    System.out.println(Thread.currentThread().getName() + "" + num);
}

}


num.getAndIncrement();这些类的底层都是直接和操作系统挂钩,在内存中修改值!Unsafe类是一个很特殊的存在!

热门文章

暂无图片
编程学习 ·

Java输出数组的内容

Java输出数组的内容_一万个小时-CSDN博客_java打印数组内容1. 输出内容最常见的方式// List<String>类型的列表List<String> list new ArrayList<String>();list.add("First");list.add("Second");list.add("Third");list.ad…
暂无图片
编程学习 ·

母螳螂的“魅惑之术”

在它们对大蝗虫发起进攻的时候&#xff0c;我认认真真地观察了一次&#xff0c;因为它们突然像触电一样浑身痉挛起来&#xff0c;警觉地面对限前这个大家伙&#xff0c;然后放下自己优雅的身段和祈祷的双手&#xff0c;摆出了一个可怕的姿势。我被眼前的一幕吓到了&#xff0c;…
暂无图片
编程学习 ·

疯狂填词 mad_libs 第9章9.9.2

#win7 python3.7.0 import os,reos.chdir(d:\documents\program_language) file1open(.\疯狂填词_d9z9d2_r.txt) file2open(.\疯狂填词_d9z9d2_w.txt,w) words[ADJECTIVE,NOUN,VERB,NOUN] str1file1.read()#方法1 for word in words :word_replaceinput(fEnter a {word} :)str1…
暂无图片
编程学习 ·

HBASE 高可用

为了保证HBASE是高可用的,所依赖的HDFS和zookeeper也要是高可用的. 通过参数hbase.rootdir指定了连接到Hadoop的地址,mycluster表示为Hadoop的集群. HBASE本身的高可用很简单,只要在一个健康的集群其他节点通过命令 hbase-daemon.sh start master启动一个Hmaster进程,这个Hmast…
暂无图片
编程学习 ·

js事件操作语法

一、事件的绑定语法 语法形式1 事件监听 标签对象.addEventListener(click,function(){}); 语法形式2 on语法绑定 标签对象.onclick function(){} on语法是通过 等于赋值绑定的事件处理函数 , 等于赋值本质上执行的是覆盖赋值,后赋值的数据会覆盖之前存储的数据,也就是on…
暂无图片
编程学习 ·

Photoshop插件--晕影动态--选区--脚本开发--PS插件

文章目录1.插件界面2.关键代码2.1 选区2.2 动态晕影3.作者寄语PS是一款栅格图像编辑软件&#xff0c;具有许多强大的功能&#xff0c;本文演示如何通过脚本实现晕影动态和选区相关功能&#xff0c;展示从互联网收集而来的一个小插件&#xff0c;供大家学习交流&#xff0c;请勿…
暂无图片
编程学习 ·

vs LNK1104 无法打开文件“xxx.obj”

写在前面&#xff1a; 向大家推荐两本新书&#xff0c;《深度学习计算机视觉实战》和《学习OpenCV4&#xff1a;基于Python的算法实战》。 《深度学习计算机视觉实战》讲了计算机视觉理论基础&#xff0c;讲了案例项目&#xff0c;讲了模型部署&#xff0c;这些项目学会之后可以…
暂无图片
编程学习 ·

工业元宇宙的定义与实施路线图

工业元宇宙的定义与实施路线图 李正海 1 工业元宇宙 给大家做一个关于工业元宇宙的定义。对于工业&#xff0c;从设计的角度来讲&#xff0c;现在的设计人员已经做到了普遍的三维设计&#xff0c;但是进入元宇宙时代&#xff0c;就不仅仅只是三维设计了&#xff0c;我们的目…
暂无图片
编程学习 ·

【leectode 2022.1.15】完成一半题目

有 N 位扣友参加了微软与力扣举办了「以扣会友」线下活动。主办方提供了 2*N 道题目&#xff0c;整型数组 questions 中每个数字对应了每道题目所涉及的知识点类型。 若每位扣友选择不同的一题&#xff0c;请返回被选的 N 道题目至少包含多少种知识点类型。 示例 1&#xff1a…
暂无图片
编程学习 ·

js 面试题总结

一、js原型与原型链 1. prototype 每个函数都有一个prototype属性&#xff0c;被称为显示原型 2._ _proto_ _ 每个实例对象都会有_ _proto_ _属性,其被称为隐式原型 每一个实例对象的隐式原型_ _proto_ _属性指向自身构造函数的显式原型prototype 3. constructor 每个prot…
暂无图片
编程学习 ·

java练习代码

打印自定义行数的空心菱形练习代码如下 import java.util.Scanner; public class daYinLengXing{public static void main(String[] args) {System.out.println("请输入行数");Scanner myScanner new Scanner(System.in);int g myScanner.nextInt();int num g%2;//…
暂无图片
编程学习 ·

RocketMQ-什么是死信队列?怎么解决

目录 什么是死信队列 死信队列的特征 死信消息的处理 什么是死信队列 当一条消息初次消费失败&#xff0c;消息队列会自动进行消费重试&#xff1b;达到最大重试次数后&#xff0c;若消费依然失败&#xff0c;则表明消费者在正常情况下无法正确地消费该消息&#xff0c;此时…
暂无图片
编程学习 ·

项目 cg day04

第4章 lua、Canal实现广告缓存 学习目标 Lua介绍 Lua语法 输出、变量定义、数据类型、流程控制(if..)、循环操作、函数、表(数组)、模块OpenResty介绍(理解配置) 封装了Nginx&#xff0c;并且提供了Lua扩展&#xff0c;大大提升了Nginx对并发处理的能&#xff0c;10K-1000K Lu…
暂无图片
编程学习 ·

输出三角形

#include <stdio.h> int main() { int i,j; for(i0;i<5;i) { for(j0;j<i;j) { printf("*"); } printf("\n"); } }
暂无图片
编程学习 ·

stm32的BOOTLOADER学习1

序言 最近计划学习stm32的BOOTLOADER学习,把学习过程记录下来 因为现在网上STM32C8T6还是比较贵的,根据我的需求flash空间小一些也可以,所以我决定使用stm32c6t6.这个芯片的空间是32kb的。 #熟悉芯片内部的空间地址 1、flash ROM&#xff1a; 大小32KB&#xff0c;范围&#xf…
暂无图片
编程学习 ·

通过awk和shell来限制IP多次访问之学不会你打死我

学不会你打死我 今天我们用shell脚本&#xff0c;awk工具来分析日志来判断是否存在扫描器来进行破解网站密码——限制访问次数过多的IP地址&#xff0c;通过Iptables来进行限制。代码在末尾 首先我们要先查看日志的格式&#xff0c;分析出我们需要筛选的内容&#xff0c;日志…
暂无图片
编程学习 ·

Python - 如何像程序员一样思考

在为计算机编写程序之前&#xff0c;您必须学会如何像程序员一样思考。学习像程序员一样思考对任何学生都很有价值。以下步骤可帮助任何人学习编码并了解计算机科学的价值——即使他们不打算成为计算机科学家。 顾名思义&#xff0c;Python经常被想要学习编程的人用作第一语言…
暂无图片
编程学习 ·

蓝桥杯python-数字三角形

问题描述 虽然我前后用了三种做法&#xff0c;但是我发现只有“优化思路_1”可以通过蓝桥杯官网中的测评&#xff0c;但是如果用c/c的话&#xff0c;每个都通得过&#xff0c;足以可见python的效率之低&#xff08;但耐不住人家好用啊&#xff08;哭笑&#xff09;&#xff09…