返回顶部
首页 > 资讯 > 后端开发 > Python >slf4j与jul、log4j1、log4j2、logback的集成原理
  • 922
分享到

slf4j与jul、log4j1、log4j2、logback的集成原理

2024-04-02 19:04:59 922人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录slf4j1 简单的使用案例2 使用原理1 获取ILoggerFactory的过程2 根据ILoggerFactory获取Logger的过程slf4j与jdk-logging集成

系列文章已完成,目录如下:

jdk-logging log4j logback日志系统实现机制原理介绍

commons-logging与jdk-logging、log4j1、log4j2、logback的集成原理

slf4j、jcl、jul、log4j1、log4j2、logback大总结

slf4j

先从一个简单的使用案例来说明

1 简单的使用案例

private static Logger logger=LoggerFactory.getLogger(Log4jslf4JTest.class);
public static void main(String[] args){
	if(logger.isDebugEnabled()){
		logger.debug("slf4j-log4j debug message");
	}
	if(logger.isInfoEnabled()){
		logger.debug("slf4j-log4j info message");
	}
	if(logger.isTraceEnabled()){
		logger.debug("slf4j-log4j trace message");
	}
}

上述Logger接口、LoggerFactory类都是slf4j自己定义的。

2 使用原理

LoggerFactory.getLogger(Log4jSlf4JTest.class)的源码如下:

public static Logger getLogger(String name) {
    ILoggerFactory iLoggerFactory = getILoggerFactory();
    return iLoggerFactory.getLogger(name);
}

上述获取Log的过程大致分成2个阶段

  • 获取ILoggerFactory的过程 (从字面上理解就是生产Logger的工厂)
  • 根据ILoggerFactory获取Logger的过程

下面来详细说明:

1 获取ILoggerFactory的过程

又可以分成3个过程:

所以slf4j与其他实际的日志框架的集成jar包中,都会含有这样的一个org/slf4j/impl/StaticLoggerBinder.class类文件,并且提供一个ILoggerFactory的实现

  • 1.1 从类路径中寻找org/slf4j/impl/StaticLoggerBinder.class类
ClassLoader.getSystemResources("org/slf4j/impl/StaticLoggerBinder.class")

如果找到多个,则输出 Class path contains multiple SLF4J bindings,表示有多个日志实现与slf4j进行了绑定

下面看下当出现多个StaticLoggerBinder的时候的输出日志(简化了一些内容):

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [slf4j-jdk14-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See Http://www.slf4j.org/codes.htmlmultiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
  • 1.2 "随机选取"一个StaticLoggerBinder.class来创建一个单例
StaticLoggerBinder.getSingleton()

这里的"随机选取"可以见官方文档说明:

SLF4J api is designed to bind with one and only one underlying logging framework at a time. If more than one binding is present on the class path, SLF4J will emit a warning, listing the location of those bindings

The warning emitted by SLF4J is just that, a warning. Even when multiple bindings are present,SLF4J will pick one logging framework/implementation and bind with it. The way SLF4J picks a binding is determined by the JVM and for all practical purposes should be considered random

  • 1.3 根据上述创建的StaticLoggerBinder单例,返回一个ILoggerFactory实例
StaticLoggerBinder.getSingleton().getLoggerFactory()

2 根据ILoggerFactory获取Logger的过程

这就要看具体的ILoggerFactory类型了,下面的集成来详细说明

slf4j与jdk-logging集成

1 需要的jar包

slf4j-api

slf4j-jdk14

对应的Maven依赖为:

<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>1.7.12</version>
</dependency>
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-jdk14</artifactId>
	<version>1.7.12</version>
</dependency>

2 使用案例

private static final Logger logger=LoggerFactory.getLogger(JulSlf4jTest.class);
public static void main(String[] args){
	if(logger.isDebugEnabled()){
		logger.debug("jul debug message");
	}
	if(logger.isInfoEnabled()){
		logger.info("jul info message");
	}
	if(logger.isWarnEnabled()){
		logger.warn("jul warn message");
	}
}

上述的Logger、LoggerFactory都是slf4j自己的API中的内容,没有jdk自带的logging的踪影,然后打出来的日志却是通过jdk自带的logging来输出的,如下:

四月 28, 2015 7:33:20 下午 com.demo.log4j.JulSlf4jTest main
信息: jul info message
四月 28, 2015 7:33:20 下午 com.demo.log4j.JulSlf4jTest main
警告: jul warn message

3 使用案例原理分析

先看下slf4j-jdk14 jar包中的内容:

从中可以看到:

  • 的确是有org/slf4j/impl/StaticLoggerBinder.class类
  • 该StaticLoggerBinder返回的ILoggerFactory类型将会是JDK14LoggerFactory
  • JDK14LoggerAdapter就是实现了slf4j定义的Logger接口

下面梳理下整个流程:

1 获取ILoggerFactory的过程

由于类路径下有org/slf4j/impl/StaticLoggerBinder.class,所以会选择slf4j-jdk14中的StaticLoggerBinder来创建单例对象并返回ILoggerFactory,来看下StaticLoggerBinder中的ILoggerFactory是什么类型:

private StaticLoggerBinder() {
    loggerFactory = new org.slf4j.impl.JDK14LoggerFactory();
}

所以返回了JDK14LoggerFactory的实例

2 根据ILoggerFactory获取Logger的过程

来看下JDK14LoggerFactory是如何返回一个slf4j定义的Logger接口的实例的,源码如下:

java.util.logging.Logger julLogger = java.util.logging.Logger.getLogger(name);
Logger newInstance = new JDK14LoggerAdapter(julLogger);

可以看到,就是使用jdk自带的logging的原生方式来先创建一个jdk自己的java.util.logging.Logger实例,参见jdk-logging的原生写法

然后利用JDK14LoggerAdapter将上述的java.util.logging.Logger包装成slf4j定义的Logger实例

所以我们使用slf4j来进行编程,最终会委托给jdk自带的java.util.logging.Logger去执行。

slf4j与log4j1集成

1 需要的jar包

slf4j-api

slf4j-log4j12

log4j

maven依赖分别为:

<!-- slf4j -->
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>1.7.12</version>
</dependency>
<!-- slf4j-log4j -->
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-log4j12</artifactId>
	<version>1.7.12</version>
</dependency>
<!-- log4j -->
<dependency>
	<groupId>log4j</groupId>
	<artifactId>log4j</artifactId>
	<version>1.2.17</version>
</dependency>

2 使用案例

第一步:编写log4j.properties配置文件,放到类路径下

log4j.rootLogger = debug, console
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} %m%n

配置文件的详细内容不是本博客关注的重点,不再说明,自行搜索

第二步:代码中如下使用

private static Logger logger=LoggerFactory.getLogger(Log4jSlf4JTest.class);
public static void main(String[] args){
	if(logger.isDebugEnabled()){
		logger.debug("slf4j-log4j debug message");
	}
	if(logger.isInfoEnabled()){
		logger.info("slf4j-log4j info message");
	}
	if(logger.isTraceEnabled()){
		logger.trace("slf4j-log4j trace message");
	}
}

补充说明:

1 配置文件同样可以随意放置,如log4j1原生方式加载配置文件的方式log4j1原生开发

2 注意两者方式的不同:

slf4j:  Logger logger=LoggerFactory.getLogger(Log4jSlf4JTest.class);
log4j:  Logger logger=Logger.getLogger(Log4jTest.class);

slf4j的Logger是slf4j定义的接口,而log4j的Logger是类。LoggerFactory是slf4j自己的类

3 使用案例原理分析

先来看下slf4j-log4j12包中的内容:

  • 的确是有org/slf4j/impl/StaticLoggerBinder.class类
  • 该StaticLoggerBinder返回的ILoggerFactory类型将会是Log4jLoggerFactory
  • Log4jLoggerAdapter就是实现了slf4j定义的Logger接口

来看下具体过程:

1 获取对应的ILoggerFactory

从上面的slf4j的原理中我们知道:ILoggerFactory是由StaticLoggerBinder来创建出来的,所以可以简单分成2个过程:

1.1 第一个过程:slf4j寻找绑定类StaticLoggerBinder

使用ClassLoader来加载 "org/slf4j/impl/StaticLoggerBinder.class"这样的类的url,然后就找到了slf4j-log4j12包中的StaticLoggerBinder

1.2 第二个过程:创建出StaticLoggerBinder实例,并创建出ILoggerFactory

源码如下:

StaticLoggerBinder.getSingleton().getLoggerFactory()

以slf4j-log4j12中的StaticLoggerBinder为例,创建出的ILoggerFactory为Log4jLoggerFactory

2 根据ILoggerFactory获取Logger的过程

来看下Log4jLoggerFactory是如何返回一个slf4j定义的Logger接口的实例的,源码如下:

org.apache.log4j.Logger log4jLogger;
if (name.equalsIgnoreCase(Logger.ROOT_LOGGER_NAME))
    log4jLogger = LogManager.getRootLogger();
else
    log4jLogger = LogManager.getLogger(name);
Logger newInstance = new Log4jLoggerAdapter(log4jLogger);

2.1 我们可以看到是通过log4j1的原生方式,即使用log4j1的LogManager来获取,引发log4j1的加载配置文件,然后初始化,最后返回一个org.apache.log4j.Logger log4jLogger,参见log4j1原生的写法

2.2 将上述的org.apache.log4j.Logger log4jLogger封装成Log4jLoggerAdapter,而Log4jLoggerAdapter是实现了slf4j的接口,所以我们使用的slf4j的Logger接口实例(这里即Log4jLoggerAdapter)都会委托给内部的org.apache.log4j.Logger实例

slf4j与log4j2集成

1 需要的jar包

slf4j-api

log4j-api

log4j-core

log4j-slf4j-impl (用于log4j2与slf4j集成)

对应的maven依赖分别是:

<!-- slf4j -->
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>1.7.12</version>
</dependency>
<!-- log4j2 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.2</version>
</dependency>
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-core</artifactId>
	<version>2.2</version>
</dependency>
<!-- log4j-slf4j-impl -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.2</version>
</dependency>

2 使用案例

第一步:编写log4j2的配置文件log4j2.xml,简单如下:、

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="debug">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

第二步:使用方式

private static Logger logger=LoggerFactory.getLogger(Log4j2Slf4jTest.class);
public static void main(String[] args){
	if(logger.isTraceEnabled()){
		logger.trace("slf4j-log4j2 trace message");
	}
	if(logger.isDebugEnabled()){
		logger.debug("slf4j-log4j2 debug message");
	}
	if(logger.isInfoEnabled()){
		logger.info("slf4j-log4j2 info message");
	}
}

3 使用案例原理分析

先来看下log4j-slf4j-impl包中的内容:

  • 的确是有org/slf4j/impl/StaticLoggerBinder.class类
  • 该StaticLoggerBinder返回的ILoggerFactory类型将会是Log4jLoggerFactory(这里的Log4jLoggerFactory与上述log4j1集成时的Log4jLoggerFactory是不一样的)
  • Log4jLogger就是实现了slf4j定义的Logger接口

来看下具体过程:

1 获取对应的ILoggerFactory

1.1 第一个过程:slf4j寻找绑定类StaticLoggerBinder

使用ClassLoader来加载 "org/slf4j/impl/StaticLoggerBinder.class"这样的类的url,然后就找到了log4j-slf4j-impl包中的StaticLoggerBinder

1.2 第二个过程:创建出StaticLoggerBinder实例,并创建出ILoggerFactory

log4j-slf4j-impl包中的StaticLoggerBinder返回的ILoggerFactory是Log4jLoggerFactory

2 根据ILoggerFactory获取Logger的过程

来看下Log4jLoggerFactory是如何返回一个slf4j定义的Logger接口的实例的,源码如下:

@Override
protected Logger newLogger(final String name, final LoggerContext context) {
    final String key = Logger.ROOT_LOGGER_NAME.equals(name) ? LogManager.ROOT_LOGGER_NAME : name;
    return new Log4jLogger(context.getLogger(key), name);
}
@Override
protected LoggerContext getContext() {
    final Class<?> anchor = ReflectionUtil.getCallerClass(FQCN, PACKAGE);
    return anchor == null ? LogManager.getContext() : getContext(ReflectionUtil.getCallerClass(anchor));
}

上述获取LoggerContext的过程也是log4j2的原生方式:

LogManager.getContext()

该操作会去加载log4j2的配置文件,引发log4j2的初始化

2.1 我们可以看到是通过log4j2的原生方式,即使用log4j2的LoggerContext来获取,返回一个org.apache.logging.log4j.core.Logger即log4j2定义的Logger接口实例,参见log4j2原生的写法

2.2 将上述的org.apache.logging.log4j.core.Logger封装成Log4jLogger,而Log4jLogger是实现了slf4j的Logger接口的,所以我们使用的slf4j的Logger接口实例(这里即Log4jLogger)都会委托给内部的log4j2定义的Logger实例。

slf4j与logback集成

1 需要的jar包

slf4j-api

logback-core

logback-classic(已含有对slf4j的集成包)

对应的maven依赖为:

<!-- slf4j-api -->
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>1.7.12</version>
</dependency>
<!-- logback -->
<dependency> 
	<groupId>ch.qos.logback</groupId> 
	<artifactId>logback-core</artifactId> 
	<version>1.1.3</version> 
</dependency> 
<dependency> 
    <groupId>ch.qos.logback</groupId> 
    <artifactId>logback-classic</artifactId> 
    <version>1.1.3</version> 
</dependency>

2 使用案例

第一步:编写logback的配置文件logback.xml,简单如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
  <root level="DEBUG">          
    <appender-ref ref="STDOUT" />
  </root>  
</configuration>

第二步:使用方式

private static final Logger logger=LoggerFactory.getLogger(LogbackTest.class);

public static void main(String[] args){
	if(logger.isDebugEnabled()){
		logger.debug("slf4j-logback debug message");
	}
	if(logger.isInfoEnabled()){
		logger.info("slf4j-logback info message");
	}
	if(logger.isTraceEnabled()){
		logger.trace("slf4j-logback trace message");
	}
}

3 使用案例原理分析

先来看下logback-classic包中与slf4j集成的内容:

  • 的确是有org/slf4j/impl/StaticLoggerBinder.class类
  • 该StaticLoggerBinder返回的ILoggerFactory类型将会是LoggerContext(logback的对象)
  • logback自己定义的ch.qos.logback.classic.Logger类就是实现了slf4j定义的Logger接口

1 获取对应的ILoggerFactory

1.1 第一个过程:slf4j寻找绑定类StaticLoggerBinder

使用ClassLoader来加载 "org/slf4j/impl/StaticLoggerBinder.class"这样的类的url,然后就找到了logback-classic包中的StaticLoggerBinder

1.2 第二个过程:创建出StaticLoggerBinder实例,并创建出ILoggerFactory

logback-classic包中的StaticLoggerBinder返回的ILoggerFactory是LoggerContext(logback的对象)

创建出单例后,同时会引发logback的初始化,这时候logback就要去寻找一系列的配置文件,尝试加载并解析。

2 根据ILoggerFactory获取Logger的过程

来看下LoggerContext(logback的对象)是如何返回一个slf4j定义的Logger接口的实例的:

该LoggerContext(logback的对象)返回的ch.qos.logback.classic.Logger(logback的原生Logger对象)就是slf4j的Logger实现类。

 结尾

本篇文章讲解了slf4j与jdk-logging、log4j1、log4j2、logback的集成原理,下一篇也是最后一篇来总结下

  • 各种jar包的总结
  • commons-logging、slf4j与其他日志框架的集成总结
  • 实现已有的日志框架无缝切换到别的日志框架(如已使用log4j进行日志记录的代码最终转到logback来输出)
  • jar包冲突说明

以上就是slf4j与jul、log4j1、log4j2、logback的集成原理的详细内容,更多关于slf4j与jul log4j1 log4j2 logback集成原理的资料请关注编程网其它相关文章!

--结束END--

本文标题: slf4j与jul、log4j1、log4j2、logback的集成原理

本文链接: https://lsjlt.com/news/143754.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • slf4j与jul、log4j1、log4j2、logback的集成原理
    目录slf4j1 简单的使用案例2 使用原理1 获取ILoggerFactory的过程2 根据ILoggerFactory获取Logger的过程slf4j与jdk-logging集成...
    99+
    2024-04-02
  • jcl与jul log4j1 log4j2 logback日志系统机制及集成原理
    目录apache commons-logging1 简单的使用案例2 使用原理1 获取LogFactory的过程2 根据LogFactory获取Log的过程commons-loggi...
    99+
    2024-04-02
  • slf4j jcl jul log4j1 log4j2 logback各组件系统日志切换
    目录各种jar包总结slf4j转向某个实际的日志框架:某个实际的日志框架转向slf4j:集成总结commons-logging与其他日志框架集成slf4j与其他日志框架集成日志系统之...
    99+
    2024-04-02
  • SpringBoot3集成SLF4J+logback进行日志记录的实现
    目录1 快速实现2 配置xml2.1 configuration2.2 property和springProperty2.3 root2.4 appender2.4.1 Consol...
    99+
    2024-04-02
  • Java日志中Slf4j、Log4J、Logback的原理总结
    本篇内容主要讲解“Java日志中Slf4j、Log4J、Logback的原理总结”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java日志中Slf4j、Log4J、Logback的原理总结”吧!...
    99+
    2023-06-16
  • ERP与PDM集成基本原理是什么
    这篇文章的内容主要围绕ERP与PDM集成基本原理是什么进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获! 1企业资源计划(ERP)概述&nbs...
    99+
    2023-06-05
  • PHP与数据治理的集成
    PHP作为一种流行的开发语言,在网络开发中扮演着重要的角色。而数据治理作为一种数据管理方式,也在企业中得到越来越多的应用。在当今互联网的快速发展中,PHP与数据治理的集成也越来越受到关注。在本文中,我们将着重探讨PHP如何集成数据治理,为企...
    99+
    2023-05-17
    PHP programming language Data management Integration
  • asp.net core 集成swagger ui的原理解析
    什么是Swagger? 说swagger 之前,我们先说一下OpenApi 规范。 OpenApi 是一种和语言无关的用于描述RESTAPIs 接口功能的一种规范,对REST...
    99+
    2024-04-02
  • jenkins持续集成的原理是什么
    Jenkins持续集成的原理是基于以下几个关键步骤: 代码检出:Jenkins会从版本控制系统(如Git)中检出最新的代码。 ...
    99+
    2023-10-25
    jenkins
  • PHP与数据流处理的集成
    随着数据处理需求不断升级,以及大数据应用的普及,数据流处理技术在近年来得到了广泛的应用。数据流处理技术的目的是在数据流中实时处理数据,以及在处理过程中同时产生新的数据流结果。PHP是一种非常流行的Web编程语言,其支持数据处理,而且在PHP...
    99+
    2023-05-17
    集成 PHP 数据流处理
  • PHP与数据库异常处理的集成
    随着互联网技术的不断进步和发展,越来越多的应用程序需要与数据库进行交互。在这个过程中,异常处理是一个非常重要的环节。PHP是一种流行的Web开发语言,有许多数据库管理系统可以很好的与之集成。本文将探讨在PHP中如何进行数据库异常处理的集成。...
    99+
    2023-05-15
    数据库 PHP 异常处理
  • PHP与数据库容量管理的集成
    随着互联网的发展,数据量的增大已经成为了各大企业和网站必须面对的问题。在数据量大的情况下,如何高效地管理数据库容量,成为了一项重要的课题。而PHP与数据库集成,为数据库容量管理提供了一种高效便捷的方法。本文将介绍PHP与数据库容量管理的集成...
    99+
    2023-05-15
    PHP 数据库管理 容量管理
  • PHP与数据库变更管理的集成
    随着Web应用程序规模和复杂性的增加,数据库变更管理成为Web开发中不可忽视的一项任务。数据库变更管理是数据库开发的核心任务之一,它指的是对数据库的结构进行更改,并确保更改不会影响应用程序的正常运行。在Web应用程序开发中,PHP与数据库变...
    99+
    2023-05-15
    数据库 PHP 变更管理
  • PHP与数据库资源管理的集成
    PHP是一种广泛应用于Web开发的脚本语言,而数据库则是Web开发中不可或缺的一部分。随着Web应用程序的不断更新和升级,需要更好的数据库资源管理方式来保证Web应用程序稳定和可靠性。针对这一需求,将PHP与数据库资源管理进行集成已经成为了...
    99+
    2023-05-15
    数据库 PHP 资源管理
  • PHP与数据库日志管理的集成
    随着互联网技术的发展,越来越多的网站或应用程序需要在后台对数据库进行管理和维护。而在这个过程中,如何记录和分析日志是非常重要的一环。PHP作为最流行的Web开发语言之一,在日志记录方面也拥有着强大的功能。本文将介绍PHP如何与数据库日志管理...
    99+
    2023-05-15
    数据库 PHP 日志管理
  • PHP与数据库错误处理的集成
    在开发过程中,数据库错误处理是非常重要的一部分。因为我们不可能保证每一个数据都是正确的、完整的,在读写数据库的过程中,一些意外的错误可能会发生。所以,开发者务必注意在程序中合理处理这些错误,以保证程序的健壮性。PHP是一门非常常用的后台编程...
    99+
    2023-05-15
    集成 PHP 数据库错误处理
  • PHP与数据库存储管理的集成
    随着互联网的发展,现代企业的业务已经越来越依赖于计算机的支持与管理,而数据库的重要性也愈发凸显。在这种情况下,无论是企业还是程序员都不可避免地需要使用数据存储管理的技术手段。PHP语言作为互联网最广泛使用的脚本语言之一,其在数据库存储管理方...
    99+
    2023-05-17
    集成 PHP 数据库管理
  • PHP与数据库异步处理的集成
    随着互联网技术的不断发展,Web应用程序已经成为互联网世界中最重要的组成部分之一。而PHP作为Web开发的一种开源脚本语言,其在Web应用程序开发中日益重要。在大多数Web应用程序中,数据处理是一个必不可少的环节。数据库是Web应用程序中最...
    99+
    2023-05-17
    数据库 PHP 异步处理
  • MySQL MHA高可用群集的原理与配置
    这篇文章主要为大家详细介绍MySQL MHA高可用群集的原理与配置,文中还介绍了MHA高可用群集的启动方法和查看MHA状态的方法,希望大家通过这篇文章能有所收获。MHA高可用架构部署配置实例一、前言1.1W...
    99+
    2024-04-02
  • Java 并发集合背后的原理与实现
    并发集合概述 在多线程编程中,多个线程可能同时访问和修改共享数据,这可能导致数据不一致或程序崩溃。为了解决这个问题,Java 提供了并发集合类,这些集合类实现了线程安全,可以确保在多线程环境下对数据的并发访问和修改是安全的。 CopyOn...
    99+
    2024-02-07
    Java 集合 并发集合 线程安全 CopyOnWriteArrayList ConcurrentHashMap ConcurrentLinkedQueue
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作