最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatisPuls多數(shù)據(jù)源操作數(shù)據(jù)源偶爾報(bào)錯(cuò)問題

 更新時(shí)間:2024年06月15日 14:09:56   作者:Q?z1997  
這篇文章主要介紹了MyBatisPuls多數(shù)據(jù)源操作數(shù)據(jù)源偶爾報(bào)錯(cuò)問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

MyBatisPuls多數(shù)據(jù)源操作數(shù)據(jù)源偶爾報(bào)錯(cuò)

昨天同事在開發(fā)一個(gè)項(xiàng)目的時(shí)候使用了 MybatisPlus 的多數(shù)據(jù)源, 但是在登陸的時(shí)候偶然就會(huì)報(bào)錯(cuò) 如下 說使用錯(cuò)庫了

但是刷新幾次有好了 我去看了看這個(gè)問題 我當(dāng)時(shí)表示十分震驚 debug 了 一個(gè)多小時(shí)也沒找到錯(cuò)誤 正當(dāng)我快放棄的時(shí)候 我想起了我以前排除過的一個(gè)問題 mybatis的 幽靈分頁 (錯(cuò)誤的使用分頁插件 導(dǎo)致的ThreadLocal 重復(fù)使用的問題)

版本是

		<dependency>
			    <groupId>com.baomidou</groupId>
			    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
			    <version>3.1.0</version>
			</dependency>

org.springframework.jdbc.BadSqlGrammarException: 
### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: Table 'constdatacenterx_company.sys_dict_type' doesn't exist
### The error may exist in vip/xiaonuo/sys/modular/dict/mapper/SysDictTypeMapper.java (best guess)
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT  id,name,code,sort,remark,status,create_time,create_user,update_time,update_user  FROM sys_dict_type     WHERE (status <> ?)
### Cause: java.sql.SQLSyntaxErrorException: Table 'constdatacenterx_company.sys_dict_type' doesn't exist
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Table 'constdatacenterx_company.sys_dict_type' doesn't exist
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:235)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:88)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440)
    at com.sun.proxy.$Proxy124.selectList(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:223)
    at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForMany(MybatisMapperMethod.java:173)
    at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:78)
    at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)
    at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
    at com.sun.proxy.$Proxy353.selectList(Unknown Source)
    at com.baomidou.mybatisplus.extension.service.IService.list(IService.java:279)
    at vip.xiaonuo.sys.modular.dict.service.impl.SysDictTypeServiceImpl.tree(SysDictTypeServiceImpl.java:199)
    at vip.xiaonuo.sys.modular.dict.service.impl.SysDictTypeServiceImpl$$FastClassBySpringCGLIB$$5dedd210.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at com.baomidou.dynamic.datasource.aop.DynamicDataSourceAnnotationInterceptor.invoke(DynamicDataSourceAnnotationInterceptor.java:50)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at vip.xiaonuo.sys.modular.dict.service.impl.SysDictTypeServiceImpl$$EnhancerBySpringCGLIB$$8ee9f21c.tree(<generated>)
    at vip.xiaonuo.sys.modular.dict.controller.SysDictTypeController.tree(SysDictTypeController.java:170)

雖然一個(gè)多小時(shí)沒有找到問題的原因 看到了mybatis plus 在切換數(shù)據(jù)源的時(shí)候使用了 ThreadLocal 直覺告訴我 可能是它的問題 但是現(xiàn)在沒有證據(jù) (不能冤枉一個(gè)好的ThreadLocal)

/**
 * Copyright ? 2018 organization baomidou
 * <pre>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * <pre/>
 */
package com.baomidou.dynamic.datasource.toolkit;

import java.util.ArrayDeque;
import java.util.Deque;
import org.springframework.core.NamedInheritableThreadLocal;
import org.springframework.util.StringUtils;

/**
 * 核心基于ThreadLocal的切換數(shù)據(jù)源工具類
 *
 * @author TaoYu Kanyuxia
 * @since 1.0.0
 */
public final class DynamicDataSourceContextHolder {

  /**
   * 為什么要用鏈表存儲(準(zhǔn)確的是棧)
   * <pre>
   * 為了支持嵌套切換,如ABC三個(gè)service都是不同的數(shù)據(jù)源
   * 其中A的某個(gè)業(yè)務(wù)要調(diào)B的方法,B的方法需要調(diào)用C的方法。一級一級調(diào)用切換,形成了鏈。
   * 傳統(tǒng)的只設(shè)置當(dāng)前線程的方式不能滿足此業(yè)務(wù)需求,必須模擬棧,后進(jìn)先出。
   * </pre>
   */
  @SuppressWarnings("unchecked")
  private static final ThreadLocal<Deque<String>> LOOKUP_KEY_HOLDER = new NamedInheritableThreadLocal("dynamic-datasource") {
    @Override
    protected Object initialValue() {
      return new ArrayDeque();
    }
  };

  private DynamicDataSourceContextHolder() {
  }

  /**
   * 獲得當(dāng)前線程數(shù)據(jù)源
   *
   * @return 數(shù)據(jù)源名稱
   */
  public static String peek() {
    return LOOKUP_KEY_HOLDER.get().peek();
  }

  /**
   * 設(shè)置當(dāng)前線程數(shù)據(jù)源
   * <p>
   * 如非必要不要手動(dòng)調(diào)用,調(diào)用后確保最終清除
   * </p>
   *
   * @param ds 數(shù)據(jù)源名稱
   */
  public static void push(String ds) {
    LOOKUP_KEY_HOLDER.get().push(StringUtils.isEmpty(ds) ? "" : ds);
  }

  /**
   * 清空當(dāng)前線程數(shù)據(jù)源
   * <p>
   * 如果當(dāng)前線程是連續(xù)切換數(shù)據(jù)源 只會(huì)移除掉當(dāng)前線程的數(shù)據(jù)源名稱
   * </p>
   */
  public static void poll() {
    Deque<String> deque = LOOKUP_KEY_HOLDER.get();
    deque.poll();
    if (deque.isEmpty()) {
      LOOKUP_KEY_HOLDER.remove();
    }
  }

  /**
   * 強(qiáng)制清空本地線程
   * <p>
   * 防止內(nèi)存泄漏,如手動(dòng)調(diào)用了push可調(diào)用此方法確保清除
   * </p>
   */
  public static void clear() {
    LOOKUP_KEY_HOLDER.remove();
  }
}

最后修改他的源碼 增加日志

/**
 * Copyright ? 2018 organization baomidou
 * <pre>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * <pre/>
 */
package com.baomidou.dynamic.datasource.toolkit;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.core.NamedInheritableThreadLocal;
import org.springframework.util.StringUtils;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * 核心基于ThreadLocal的切換數(shù)據(jù)源工具類
 *
 * @author TaoYu Kanyuxia
 * @since 1.0.0
 */
public final class DynamicDataSourceContextHolder {

    /**
     * 為什么要用鏈表存儲(準(zhǔn)確的是棧)
     * <pre>
     * 為了支持嵌套切換,如ABC三個(gè)service都是不同的數(shù)據(jù)源
     * 其中A的某個(gè)業(yè)務(wù)要調(diào)B的方法,B的方法需要調(diào)用C的方法。一級一級調(diào)用切換,形成了鏈。
     * 傳統(tǒng)的只設(shè)置當(dāng)前線程的方式不能滿足此業(yè)務(wù)需求,必須模擬棧,后進(jìn)先出。
     * </pre>
     */
    private static final ThreadLocal<Deque<String>> LOOKUP_KEY_HOLDER = new NamedInheritableThreadLocal<Deque<String>>("dynamic-datasource") {
        // @Override
        // protected Deque<String> childValue(Deque<String> parentValue) {
        //     return new ArrayDeque<>();
        // }

        @Override
        protected ArrayDeque<String> initialValue() {
            return new ArrayDeque<>();
        }
    };

    private DynamicDataSourceContextHolder() {
    }

    /**
     * 獲得當(dāng)前線程數(shù)據(jù)源
     *
     * @return 數(shù)據(jù)源名稱
     */
    public static String peek() {
        Deque<String> strings = LOOKUP_KEY_HOLDER.get();
        String peek = strings.peek();
        String format = LocalDateTimeUtil.format(LocalDateTimeUtil.now(), "yyyy-MM-dd HH:mm:ss:SSS");
        System.out.printf("時(shí)間 %s 當(dāng)前線程 %s 獲得當(dāng)前線程數(shù)據(jù)源 %s 棧針 %s ", format, Thread.currentThread().getName(), peek, JSON.toJSONString(strings));
        System.out.println();
        return peek;
    }

    /**
     * 設(shè)置當(dāng)前線程數(shù)據(jù)源
     * <p>
     * 如非必要不要手動(dòng)調(diào)用,調(diào)用后確保最終清除
     * </p>
     *
     * @param ds 數(shù)據(jù)源名稱
     */
    public static void push(String ds) {
        Deque<String> strings = LOOKUP_KEY_HOLDER.get();
        System.out.printf("時(shí)間 %s 當(dāng)前線程 %s 設(shè)置當(dāng)前線程數(shù)據(jù)源 %s 棧針 %s 引用 %s", LocalDateTimeUtil.format(LocalDateTimeUtil.now(), "yyyy-MM-dd HH:mm:ss:SSS"), Thread.currentThread().getName(), ds, JSON.toJSONString(strings), strings.hashCode());
        System.out.println();
        strings.push(StringUtils.isEmpty(ds) ? "" : ds);
        System.out.printf("時(shí)間 %s 當(dāng)前線程 %s 之后設(shè)置當(dāng)前線程數(shù)據(jù)源 %s 棧針 %s 引用 %s", LocalDateTimeUtil.format(LocalDateTimeUtil.now(), "yyyy-MM-dd HH:mm:ss:SSS"), Thread.currentThread().getName(), ds, JSON.toJSONString(strings), strings.hashCode());
        System.out.println();
    }

    /**
     * 清空當(dāng)前線程數(shù)據(jù)源
     * <p>
     * 如果當(dāng)前線程是連續(xù)切換數(shù)據(jù)源 只會(huì)移除掉當(dāng)前線程的數(shù)據(jù)源名稱
     * </p>
     */
    public static void poll() {
        Deque<String> deque = LOOKUP_KEY_HOLDER.get();
        System.out.printf("時(shí)間 %s 清空當(dāng)前線程 %s  棧針 %s ", LocalDateTimeUtil.format(LocalDateTimeUtil.now(), "yyyy-MM-dd HH:mm:ss:SSS"), Thread.currentThread().getName(), JSON.toJSONString(deque));
        System.out.println();
        String poll = deque.poll();
        System.out.printf("時(shí)間 %s 當(dāng)前線程 %s 清空 %s 棧針 %s ", LocalDateTimeUtil.format(LocalDateTimeUtil.now(), "yyyy-MM-dd HH:mm:ss:SSS"), Thread.currentThread().getName(), poll, JSON.toJSONString(deque));
        System.out.println();
        if (deque.isEmpty()) {
            LOOKUP_KEY_HOLDER.remove();
        }
    }

    /**
     * 強(qiáng)制清空本地線程
     * <p>
     * 防止內(nèi)存泄漏,如手動(dòng)調(diào)用了push可調(diào)用此方法確保清除
     * </p>
     */
    public static void clear() {
        LOOKUP_KEY_HOLDER.remove();
    }
}

當(dāng)我查看日志的時(shí)候 讓我發(fā)現(xiàn)了一個(gè) 令我震驚的是 ThreadLocal 維護(hù)的value 竟然兩個(gè)線程共享了 震驚!!!

    /**
     * 設(shè)置當(dāng)前線程數(shù)據(jù)源
     * <p>
     * 如非必要不要手動(dòng)調(diào)用,調(diào)用后確保最終清除
     * </p>
     *
     * @param ds 數(shù)據(jù)源名稱
     */
    public static void push(String ds) {
        Deque<String> strings = LOOKUP_KEY_HOLDER.get();
        System.out.printf("時(shí)間 %s 當(dāng)前線程 %s 設(shè)置當(dāng)前線程數(shù)據(jù)源 %s 棧針 %s 引用 %s", LocalDateTimeUtil.format(LocalDateTimeUtil.now(), "yyyy-MM-dd HH:mm:ss:SSS"), Thread.currentThread().getName(), ds, JSON.toJSONString(strings), strings.hashCode());
        System.out.println();
        strings.push(StringUtils.isEmpty(ds) ? "" : ds);
        System.out.printf("時(shí)間 %s 當(dāng)前線程 %s 之后設(shè)置當(dāng)前線程數(shù)據(jù)源 %s 棧針 %s 引用 %s", LocalDateTimeUtil.format(LocalDateTimeUtil.now(), "yyyy-MM-dd HH:mm:ss:SSS"), Thread.currentThread().getName(), ds, JSON.toJSONString(strings), strings.hashCode());
        System.out.println();
    }

所以出現(xiàn)了上述的查詢數(shù)據(jù)異常 !!!

但是這不符合常理的 ThreadLocal 肯定沒有線程安全問題 我將這個(gè)變量修改成 NamedInheritableThreadLocal 改成 ThreadLocal 測試發(fā)現(xiàn)也沒有問題了

我們來看看這個(gè) NamedInheritableThreadLocal 類吧

package org.springframework.core;

import org.springframework.util.Assert;

public class NamedInheritableThreadLocal<T> extends InheritableThreadLocal<T> {
    private final String name;

    public NamedInheritableThreadLocal(String name) {
        Assert.hasText(name, "Name must not be empty");
        this.name = name;
    }

    public String toString() {
        return this.name;
    }
}

這個(gè)childValue 方法的描述很有趣

為這個(gè)可繼承的線程局部計(jì)算子線程的初始值變量作為父變量在子變量出現(xiàn)時(shí)的值的函數(shù)創(chuàng)建線程。

此方法從父類內(nèi)部調(diào)用 子線程啟動(dòng)之前的線程。

就是子線程可以基礎(chǔ)父線程的 ThreadLocal 中的變量 看到這終于明白了 就是這個(gè)的問題了

來仔細(xì)聊聊這個(gè)InheritableThreadLocal

首先我們知道ThreadLocal解決的是變量在不同線程間的隔離性,也就是不同線程擁有自己的值。類ThreadLocal的主要作用是將數(shù)據(jù)放入當(dāng)前線程對象中的Map中,類ThreadLocal自己不管理、不存儲任何數(shù)據(jù),它只是數(shù)據(jù)和Map之間的橋梁,Map中的key存儲的是ThreadLocal對象,value就是存儲的值。每個(gè)Thread中的Map值只對當(dāng)前線程可見,其他線程不可以訪問當(dāng)前線程對象中Map的值。

當(dāng)前線程銷毀,Map隨之銷毀,Map中的數(shù)據(jù)如果沒有被引用、沒有被使用,則隨時(shí)GC收回。由于Map中的key不可以重復(fù),所以一個(gè)ThreadLocal對象對應(yīng)一個(gè)value。

Thread類中有一個(gè)init方法,每次創(chuàng)建線程的時(shí)候會(huì)執(zhí)行這個(gè)init方法,并且inheriThreadLocals默認(rèn)傳的參數(shù)是true,所以當(dāng)前線程對象每次都會(huì)從父線程繼承值,子線程將父線程中的table對象以復(fù)制的方式賦值給子線程的table數(shù)組,這個(gè)過程是在創(chuàng)建Thread類對象時(shí)發(fā)生的,也就說明當(dāng)子線程對象創(chuàng)建完畢后,子線程中的數(shù)據(jù)就是主線程中舊的數(shù)據(jù),主線程使用新的數(shù)據(jù)時(shí),子線程還是使用舊的數(shù)據(jù),因?yàn)橹髯泳€程使用兩個(gè)Entry[]對象數(shù)組各自存儲自己的值。

這個(gè)復(fù)制其實(shí)一個(gè)淺拷貝,如果存的值是可變對象的時(shí)候,只是復(fù)制了對象的引用而已,如果父線程修改對象的屬性值,子線程也是可以感知到的。

在我這個(gè)問題是 就是 http-nio-82-exec-9 創(chuàng)建了線程http-nio-82-exec-10 導(dǎo)致了這個(gè)問題

解決方法

重寫childValue 或者 直接使用 ThreadLocal

    /**
     * 為什么要用鏈表存儲(準(zhǔn)確的是棧)
     * <pre>
     * 為了支持嵌套切換,如ABC三個(gè)service都是不同的數(shù)據(jù)源
     * 其中A的某個(gè)業(yè)務(wù)要調(diào)B的方法,B的方法需要調(diào)用C的方法。一級一級調(diào)用切換,形成了鏈。
     * 傳統(tǒng)的只設(shè)置當(dāng)前線程的方式不能滿足此業(yè)務(wù)需求,必須模擬棧,后進(jìn)先出。
     * </pre>
     */
    private static final ThreadLocal<Deque<String>> LOOKUP_KEY_HOLDER = new NamedInheritableThreadLocal<Deque<String>>("dynamic-datasource") {
        @Override
        protected Deque<String> childValue(Deque<String> parentValue) {
            return new ArrayDeque<>();
        }

        @Override
        protected ArrayDeque<String> initialValue() {
            return new ArrayDeque<>();
        }
    };

最后去看官方文檔

人家修復(fù)了 嗚嗚嗚嗚嗚嗚嗚

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot 定時(shí)任務(wù)遇到的坑

    SpringBoot 定時(shí)任務(wù)遇到的坑

    這篇文章主要介紹了SpringBoot 定時(shí)任務(wù)遇到的坑,今天踩的這個(gè)坑和 cron 表達(dá)式有關(guān),文中給大家介紹了cron 表達(dá)式的解釋,需要的朋友一起看看吧
    2017-11-11
  • SpringBoot如何動(dòng)態(tài)修改Scheduled(系統(tǒng)啟動(dòng)默認(rèn)執(zhí)行,動(dòng)態(tài)修改)

    SpringBoot如何動(dòng)態(tài)修改Scheduled(系統(tǒng)啟動(dòng)默認(rèn)執(zhí)行,動(dòng)態(tài)修改)

    這篇文章主要介紹了SpringBoot如何動(dòng)態(tài)修改Scheduled(系統(tǒng)啟動(dòng)默認(rèn)執(zhí)行,動(dòng)態(tài)修改)的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • SpringBoot3.4配置校驗(yàn)新特性的用法詳解

    SpringBoot3.4配置校驗(yàn)新特性的用法詳解

    Spring Boot 3.4 對配置校驗(yàn)支持進(jìn)行了全面升級,這篇文章為大家詳細(xì)介紹了一下它們的具體使用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下
    2025-04-04
  • Java使用Runnable接口創(chuàng)建線程的示例代碼

    Java使用Runnable接口創(chuàng)建線程的示例代碼

    在Java中,多線程編程是實(shí)現(xiàn)并發(fā)操作的重要手段之一,通過多線程,程序可以同時(shí)執(zhí)行多個(gè)任務(wù),從而提高應(yīng)用程序的效率和響應(yīng)速度,Java提供了多種創(chuàng)建線程的方式,其中實(shí)現(xiàn)Runnable接口是最常見且推薦的方式之一,本文將詳細(xì)介紹如何使用Runnable接口創(chuàng)建線程
    2025-02-02
  • 使用IntelliJ IDEA查看類的繼承關(guān)系圖形(圖文詳解)

    使用IntelliJ IDEA查看類的繼承關(guān)系圖形(圖文詳解)

    這篇文章主要介紹了使用IntelliJ IDEA查看類的繼承關(guān)系圖形,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的工作或?qū)W習(xí)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • JavaWeb中的簡單分頁完整代碼(推薦)

    JavaWeb中的簡單分頁完整代碼(推薦)

    這次主要是講解一下通過登錄后對得到的數(shù)據(jù)進(jìn)行分頁,首先我們新建一個(gè)登錄頁面login.jsp,因?yàn)槲覀冎饕獙W(xué)習(xí)的分頁,所以登錄驗(yàn)證的部分沒有提到。關(guān)于javaweb中的分頁代碼大家通過本文學(xué)習(xí)吧
    2016-11-11
  • Java?離線中文語音文字識別功能的實(shí)現(xiàn)代碼

    Java?離線中文語音文字識別功能的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Java?離線中文語音文字識別,本次使用springboot?+maven實(shí)現(xiàn),官方demo為springboot+gradle,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • 創(chuàng)建并運(yùn)行一個(gè)java線程方法介紹

    創(chuàng)建并運(yùn)行一個(gè)java線程方法介紹

    這篇文章主要介紹了創(chuàng)建并運(yùn)行一個(gè)java線程,涉及線程代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • java計(jì)算百分比值的方法

    java計(jì)算百分比值的方法

    這篇文章主要介紹了java計(jì)算百分比值的方法,涉及java數(shù)值運(yùn)算的技巧,需要的朋友可以參考下
    2015-03-03
  • springboot文件上傳時(shí)maxPostSize設(shè)置大小失效問題及解決

    springboot文件上傳時(shí)maxPostSize設(shè)置大小失效問題及解決

    這篇文章主要介紹了springboot文件上傳時(shí)maxPostSize設(shè)置大小失效問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07

最新評論

房山区| 宜都市| 通辽市| 镇原县| 土默特右旗| 来宾市| 盘山县| 翁牛特旗| 佳木斯市| 阿鲁科尔沁旗| 探索| 长治县| 焉耆| 容城县| 开鲁县| 和田县| 宁国市| 磴口县| 深圳市| 恭城| 洛阳市| 武山县| 沁阳市| 志丹县| 婺源县| 洪江市| 南华县| 澎湖县| 怀柔区| 同江市| 嘉义县| 涞水县| 图们市| 锡林浩特市| 吉林市| 瓦房店市| 开平市| 庆阳市| 新平| 叙永县| 陆河县|