• Java程序猿搬砖笔记(十)


    synchronized锁定的对象

    synchronized修饰的作用:
    让多个线程排队依次获取某个资源,保证数据不会出错(原子性)。
    synchronized锁定的元素:

    • 修饰方法
      • 静态方法,锁定的是类
      • 普通方法,锁定的时方法的调用者
    • 修饰代码块,锁定的时传入的对象

    Java线程内存模型(JMM)定义的8中原子操作

    • read(读取):从主内存中读取数据
    • load(载入):将主内存读取到的数据写入工作内存
    • use(使用):从工作内存读取数据来计算
    • assgin(赋值):将计算好的值重新赋值到工作内存中
    • store(存储):将工作内存数据写入主内存,会经过总线,到总线后就开始广播其他线程
    • write(写入):将store过去的变量值赋值给主内存中的变量
    • lock(锁定):将主内存变量加锁,标识为线程独占状态
    • unlock(解锁):将主内存变量解锁,解锁后其他线程可以锁定该变量
      MESI缓存一致性协议:
      多个cpu从主内存读取同一个数据到各自的高速缓存,当其中某个cpu修改了缓存里的数据,该数据会马上同步回主内存,其他cpu通过总线嗅探机制可以感知到数据的变化从而将自己缓存里的数据失效。
      一般lock锁加在线程的赋值之后,存储之前,这样的锁的粒度不大。volatile保证数据可见性、synchronized保证原子性。

    MySQL分区学习

    参考链接参考链接参考链接

    根据hash中的键模糊删除

    /**
     * 根据hash中的键模糊删除
     * @param key key redis的key
     * @param item item hash的键
     */
    public  void removeHashItem(String key, String item){
    
    	ArrayList<String> items = new ArrayList<>();
    	// 模糊查询出准确的item
    	redisTemplate.execute(new RedisCallback() {
    		@Override
    		public Object doInRedis(RedisConnection connection) throws DataAccessException {
    			Cursor<Map.Entry<byte[], byte[]>> entryCursor = connection.hScan(key.getBytes(), ScanOptions.scanOptions().match("*" + item + "*").count(1800).build());
    			while(entryCursor.hasNext()){
    				Map.Entry<byte[], byte[]> next = entryCursor.next();
    				String key = new String(next.getKey());
    				// 将查询出的item放入list
    				items.add(key);
    			}
    			connection.close();
    			return null;
    		}
    	});
    	// 批量删除对应key中的item
    	for (String str: items){
    		redisTemplate.opsForHash().delete(key, str);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    union和ordery by一起使用报"Incorrect usage of UNION and ORDER BY"错误的解决方法

    原因

    每条字句都使用order by会报错。

    解决方法

    方法一:只在最后一条字句使用order by,意思是对整个结果集进行order by
    参考代码如下:

    select * from t1 where username like 'l%'
    union
    select * from t1 where username like '%m%'
    order by score asc
    
    • 1
    • 2
    • 3
    • 4

    方法二:union后整体改为临时表
    参考代码如下:

    select * from 
    (select * from t1 where username like 'l%'
    union
    select * from t1 where username like '%m%')tmp
    order by tmp.score asc
    
    • 1
    • 2
    • 3
    • 4
    • 5

    方法三:每一层都改为临时表再union

    select * from (select * from t1 where username like 'l%') t1
    union
    select * from (select * from t1 where username like '%m%') t2
    order by score asc
    
    • 1
    • 2
    • 3
    • 4

    参考链接

    Spring Cloud Config多服务共享公共配置

    参考代码:

    spring:
      application:
        name: innovation
      cloud:
        config:
          name: reward-innovation-v1,common
          profile: test
          uri: http://10.12.7.124:8888
          failFast: true
          enabled: true
      main.allow-bean-definition-overriding: true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    该代码读取配置中心的common-test.yml和reward-innovation-v1-test.yml文件

    参考链接

    解决SpringBoot启动报错:NoClassDefFoundError: org/springframework/data/redis/connection/RedisStreamCommands

    查重管理的时候,在测试环境碰到一模一样的问题。

    参考链接

    查看Java进程当前使用的JVM参数

    1、jps命令查看当前进程id

    [award_dev@localhost reward_taskjob]$ jps -l
    32496 reward-taskjob-202209151113-SNAPSHOT.jar
    4931 award-webbas-config-2022-08-29-122959.jar
    3187 reward-innovation-202209172040-SNAPSHOT.jar
    
    • 1
    • 2
    • 3
    • 4

    2、jinfo -flags 进程id 命令查看当前进程使用的JVM参数

    [award_dev@localhost reward_taskjob]$ jinfo -flags 32496
    Attaching to process ID 32496, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.121-b13
    Non-default VM flags: -XX:CICompilerCount=12 -XX:ConcGCThreads=3 -XX:G1HeapRegionSize=1048576 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=null -XX:InitialHeapSize=1289748480 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=2147483648 -XX:MaxNewSize=1287651328 -XX:MinHeapDeltaBytes=1048576 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC
    Command line:  -Dlog4j2.formatMsgNoLookups=true -DENV_CONFIG_IP=10.12.7.181 -DENV_CONFIG_PORT=9888 -DENV_TYPE=dev -Dname=reward-taskjob-202209151113-SNAPSHOT.jar -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Duser.timezone=Asia/Shanghai -Djava.io.tmpdir=/opt/aspire/product/award_dev/reward_taskjob/data/tmp -Xms1230m -Xmx2g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./logs/java_heapdump.hprof -XX:+PrintGCDateStamps -Xloggc:/opt/aspire/product/award_dev/reward_taskjob/logs/gclog/gc-reward-taskjob-202209151113-SNAPSHOT.jar-20220919102315.log -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+UseG1GC
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    RestTemplate使用Ribbon实现负载均衡的调用

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
    	return new RestTemplate();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    直接通过服务名调用,Eureka会去找。

    restTemplate.postForObject("http://webbas32-manage-v1/web/login/findemployeebyphone", formEntity, String.class);
    
    • 1

    其中webbas32-manage-v1为接口提供方的服务名
    调用方的Eureka配置需要添加,fetchRegistry: true //表示可以从Eureka Server获取注册的服务信息

    RestTemplate.postForObject泛型丢失(返回LinkedHashMap)的问题解决方法

    问题:
    在这里插入图片描述
    如上图所示,data类型本应该为MemberInfoVo,但是泛型丢失变为LinkedHashMap。

    解决方法:
    参考代码如下:

    ParameterizedTypeReference<ResponseMsg<MemberInfoVo>> typeRef = new ParameterizedTypeReference<ResponseMsg<MemberInfoVo>>() {};
    ResponseEntity<ResponseMsg<MemberInfoVo>> result = restTemplate.exchange(findEmployeeUrl, HttpMethod.POST, formEntity, typeRef);
    ResponseMsg<MemberInfoVo> responseMsg = result.getBody(); 
    
    • 1
    • 2
    • 3

    成功效果:
    在这里插入图片描述
    参考链接

    MyBatis批量更新

    参考链接

    Spring Cloud Eureka自我保护机制

    参考链接

    Spring Cloud Eureka控制台相关配置参数学习

    参考链接

    SpringBoot配置默认sql级别info、sql打印级别为debug

    SpringBoot的默认使用的日志框架为logback,且默认的日志级别均为INFO。
    为了打印sql日志信息,我们只需把对应dao层包下的日志级别改为DEBUG。

    示例代码如下:

    # log  
    logging:
      config: classpath:log4j2-dev.xml
      level:
        root: info
    	# dao层包下的日志级别修改
        com:
          aspirecn:
            rewardmanagement:
              mapper: debug
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    参考链接

    IDEA解决完所有冲突但是分支还是在Merging状态的解决方法

    1、通过git status命令查看信息(关键):
    All conflicts fixed but you are still merging(use “git commit” to conclude merge)
    2、根据第一步的信息提示做操作
    示例操作如下:

    git add -A
    git commit -m '合并master'
    
    • 1
    • 2

    参考链接

    SpringBoot中使用@Value读取配置文件中的list、map

    配置文件代码:

    myList: item1,item2,item3
    myMap: "{key1: 'value1', key2: 'value2'}"
    
    • 1
    • 2

    Java代码:

    @Value("#{'${myList}'.split(',')}")
    private List<String> myList;
     
    @Value("#{${myMap}}")  
    private Map<String,String> myMap;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意:
    上面的list配置中,一定不要用""把list所有的成员value包起来,要不然解析报错。
    上面的map配置中,一定要用"" 把map所对应的value包起来,要不然解析解析报错。

    参考链接

    SpringBoot中多个@ControllerAdvice全局异常处理

    多个ControllerAdvice,优先级由@Order决定,order的数值越小 则优先级越高。

    import org.springframework.core.Ordered;
    import org.springframework.core.annotation.Order;
    
    @ControllerAdvice
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public class MsControllerAdvice {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意:@ControllerAdvice只能对controller抛出的异常处理

    多个@ControllerAdvice全局异常处理(含多个实用场景)
    @ControllerAdvice优先级设定

    SpringCloud zuul路由手动配置

    示例代码:

    zuul:
      routes:
        api-a:
          path: /api-a/**
          serviceId: service-ribbon
        api-b:
          path: /api-b/**
          serviceId: service-feign
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    zuul路由配置说明:api-a、api-b是路由名称可以随便取,serviceId是服务的id(对应spring.application.name)。
    上面配置表示,以/api-a/ 开头的请求都转发给service-ribbon服务;以/api-b/开头的请求都转发给service-feign服务。

    SpringCloud zuul的路由默认自动配置

    zuul可以自动根据Eureka服务器中所注册的服务自动完成路由映射、负载均衡。
    在Eureka上注册了两个服务:
    1、服务名management,端口18081
    2、服务名gateway,端口7001
    请求路径,127.0.0.1:7001/management/addressBook/getList,网关zuul会把请求转发给management服务,
    实际请求路径127.0.0.1:18081/addressBook/getList

    参考链接

    dependencyManagement标签的作用

    在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器。
    jar的版本判断的两种途径:

    • 如果dependencies里的dependency自己没有声明version元素,那么maven就会到dependencyManagement里面去找有没有对该artifactId和groupId进行过版本声明。如果有,就继承它,如果没有就会报错,告诉你必须为dependency声明一个version。
    • 如果dependencies中的dependency声明了version,那么无论dependencyManagement中有无对该jar的version声明,都以dependency里的version为准。

    示例代码如下:

    
    <dependencyManagement>  
          <dependencies>  
                <dependency>  
                    <groupId>org.springframeworkgroupId>  
                    <artifactId>spring-coreartifactId>  
                    <version>3.2.7version>  
                dependency>  
        dependencies>  
    dependencyManagement>  
      
     
    <dependencies>  
           <dependency>  
                    <groupId>org.springframeworkgroupId>  
                    <artifactId>spring-coreartifactId>  
           dependency>  
    dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    参考链接

  • 相关阅读:
    PHP知识大全
    关于浏览器Devtools的open,close监听
    网络编程1
    SpringBoot 整合 Neo4j
    【超简便的Python】 提取两个列表的共同元素
    Excel中将单元格格式改成文本后,为何要双击数字才会改变?
    XCC批量更新固件微码
    LeetCode 1656. 设计有序流
    Vue+element-ui实现表格数据渲染+分页
    【PTA】递归练习_输出1到n的全排列
  • 原文地址:https://blog.csdn.net/a1275302036/article/details/126691622