java学习笔记

java学习笔记


redis

类型

在这里插入图片描述

哈希的操作命令

在这里插入图片描述

列表的操作命令

在这里插入图片描述

集合的操作命令

在这里插入图片描述

有序集合的操作命令

在这里插入图片描述

lamdba

静态方法引用

在这里插入图片描述

特定方法引用

在这里插入图片描述
在这里插入图片描述

构造器引用

在这里插入图片描述

springCloud

nacos

在这里插入图片描述

gateway

openFeign

在这里插入图片描述

调用第三方地址

在这里插入图片描述

超时

在这里插入图片描述
在这里插入图片描述

兜底

在这里插入图片描述

sentinel

在这里插入图片描述
在这里插入图片描述

异常处理

在这里插入图片描述

MQ

消费者确认

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

业务幂等性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

延迟消息

在这里插入图片描述

死信交换机

在这里插入图片描述

延迟消息插件

在这里插入图片描述

并发问题

乐观锁

在这里插入图片描述
在这里插入图片描述

分布式锁

redis锁

在这里插入图片描述

/**
 * 采用SpringDataRedis实现分布式锁
 * 原理:执行业务方法前先尝试获取锁(setnx存入key val),如果获取锁成功再执行业务代码,业务执行完毕后将锁释放(del key)
 */
@Override
public void testLock() {

    //0.先尝试获取锁 setnx key val
    Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent("lock", "lock");
    if(flag){
        //获取锁成功,执行业务代码
        //1.先从redis中通过key num获取值  key提前手动设置 num 初始值:0
        String value = stringRedisTemplate.opsForValue().get("num");
        //2.如果值为空则非法直接返回即可
        if (StringUtils.isBlank(value)) {
            return;
        }
        //3.对num值进行自增加一
        int num = Integer.parseInt(value);
        stringRedisTemplate.opsForValue().set("num", String.valueOf(++num));

        //4.将锁释放
        stringRedisTemplate.delete("lock");

    }else{
        try {
            Thread.sleep(100);
            this.testLock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

redisson

Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service) Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
</dependency>```




```java
package com.atguigu.daijia.common.config.redssion;

import lombok.Data;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

/**
 * redisson配置信息
 */
@Data
@Configuration
@ConfigurationProperties("spring.data.redis")
public class RedissonConfig {

    private String host;

    private String password;

    private String port;

    private int timeout = 3000;
    private static String ADDRESS_PREFIX = "redis://";

    /**
     * 自动装配
     *
     */
    @Bean
    RedissonClient redissonSingle() {
        Config config = new Config();

        if(!StringUtils.hasText(host)){
            throw new RuntimeException("host is  empty");
        }
        SingleServerConfig serverConfig = config.useSingleServer()
                .setAddress(ADDRESS_PREFIX + this.host + ":" + port)
                .setTimeout(this.timeout);
        if(StringUtils.hasText(this.password)) {
            serverConfig.setPassword(this.password);
        }
        return Redisson.create(config);
    }
}

使用

@Autowired
private RedissonClient redissonClient;

/**
 * 使用Redison实现分布式锁
 * 开发步骤:
 * 1.使用RedissonClient客户端对象 创建锁对象
 * 2.调用获取锁方法
 * 3.执行业务逻辑
 * 4.将锁释放
 *
 */
public void testLock() {

    //0.创建锁对象
    RLock lock = redissonClient.getLock("lock1");

    //0.1 尝试加锁
    //0.1.1 lock() 阻塞等待一直到获取锁,默认锁有效期30s
    lock.lock();

    //1.先从redis中通过key num获取值  key提前手动设置 num 初始值:0
    String value = stringRedisTemplate.opsForValue().get("num");
    //2.如果值为空则非法直接返回即可
    if (StringUtils.isBlank(value)) {
        return;
 }
    //3.对num值进行自增加一
    int num = Integer.parseInt(value);
    stringRedisTemplate.opsForValue().set("num", String.valueOf(++num));

    //4.将锁释放
    lock.unlock();

}

分布式事务

事务ACID四大特性

A:原子性(Atomicity)

一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

C:一致性(Consistency)

事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。

如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。

如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。

I:隔离性(Isolation)

指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。

D:持久性(Durability)

指的是只要事务成功结束,它对数据库所做的更新就必须保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

事务的并发问题

脏读**:** ​

事务A读取了事务B更新的数据,事务B未提交并回滚数据,那么A读取到的数据是脏数据

不可重复读**:** ​

事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

幻读**:** ​

系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A更改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。

本地事务(单个数据库)

在这里插入图片描述

分布式事务(多个数据库)

seata

在这里插入图片描述
在这里插入图片描述

飞算

飞算AI插件下载指引:
👉下载地址(PC端打开):https://feisuanyz.com/home
👉使用手册:https://www.feisuanyz.com/docs/languages/help.html

注意:IDEA版本支持2020.3.0到2024.3

completableFuture

多线程

创建方式

继承Thread类

在这里插入图片描述

实现Runnable接口

在这里插入图片描述

/**
 * @author Mr.乐
 * @Description
 */
public class Demo02 {
    public static void main(String[] args) {
        MyRunnable myRun = new MyRunnable();//将一个任务提取出来,让多个线程共同去执行
        //封装线程对象
        Thread t01 = new Thread(myRun, "线程01");
        Thread t02 = new Thread(myRun, "线程02");
        Thread t03 = new Thread(myRun, "线程03");
        //开启线程
        t01.start();
        t02.start();
        t03.start();
        //通过匿名内部类的方式创建线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName() + " - " + i);
                }
            }
        },"线程04").start();
    }
}
//自定义线程类,实现Runnable接口
//这并不是一个线程类,是一个可运行的类,它还不是一个线程。
class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
        }
    }
}
实现Callable接口

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
 * @author Mr.乐
 * @Description  线程实现的第三种方式
 */
public class Demo04 {
    public static void main(String[] args) throws Exception {
 
        // 第一步:创建一个“未来任务类”对象。
        // 参数非常重要,需要给一个Callable接口实现类对象。
        FutureTask task = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception { // call()方法就相当于run方法。只不过这个有返回值
                // 线程执行一个任务,执行之后可能会有一个执行结果
                // 模拟执行
                System.out.println("call method begin");
                Thread.sleep(1000 * 10);
                System.out.println("call method end!");
                int a = 100;
                int b = 200;
                return a + b; //自动装箱(300结果变成Integer)
            }
        });
 
        // 创建线程对象
        Thread t = new Thread(task);
 
        // 启动线程
        t.start();
 
        // 这里是main方法,这是在主线程中。
        // 在主线程中,怎么获取t线程的返回结果?
        // get()方法的执行会导致“当前线程阻塞”
        Object obj = task.get();
        System.out.println("线程执行结果:" + obj);
        // main方法这里的程序要想执行必须等待get()方法的结束
        // 而get()方法可能需要很久。因为get()方法是为了拿另一个线程的执行结果
        // 另一个线程执行是需要时间的。
        System.out.println("hello world!");
    }
}

线程常用方法

在这里插入图片描述

线程同步(解决线程安全的问题)

在这里插入图片描述

同步代码块

锁对象必须保证唯一,静态方法推荐使用类,非静态方法推荐使用this;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

同步方法

在这里插入图片描述

在这里插入图片描述

Lock锁

在这里插入图片描述

在这里插入图片描述

线程池

在这里插入图片描述

线程池常用方法

在这里插入图片描述

处理Runanble

在这里插入图片描述
在这里插入图片描述

处理Callbale

在这里插入图片描述

Executors线程池工具类

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值