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

使用Java實(shí)現(xiàn)一個(gè)解析CURL腳本小工具

 更新時(shí)間:2025年02月08日 09:28:08   作者:路 飛  
文章介紹了如何使用Java實(shí)現(xiàn)一個(gè)解析CURL腳本的工具,該工具可以將CURL腳本中的Header解析為KV Map結(jié)構(gòu),獲取URL路徑、請(qǐng)求類型,解析URL參數(shù)列表和Body請(qǐng)求體,感興趣的小伙伴跟著小編一起來看看吧

版本

時(shí)間

修改內(nèi)容

V1

2024.06.13

新建

V2

2024.06.28

更新body和請(qǐng)求類型篩選的正則表達(dá)式內(nèi)容,特殊換符和轉(zhuǎn)移符剔除

該工具可以將CURL腳本中的Header解析為KV Map結(jié)構(gòu);獲取URL路徑、請(qǐng)求類型;解析URL參數(shù)列表;解析Body請(qǐng)求體:Form表單、Raw Body、KV Body、XML/JSON/TEXT結(jié)構(gòu)體等。

使用示例

獲取一個(gè)http curl腳本:

curl --location --request POST 'https://cainiao-inc.com?param_1=value_1&param_2=value_2' \
--header 'Cookie: USER_COOKIE' \
--header 'Content-Type: application/json' \
--data-raw '{
    "appName": "link",
    "apiId": "TEST_API",
    "content": {
        "address": "Cainiao Home",
        "city": "Hangzhou"
    }
}'

執(zhí)行解析例子:

實(shí)現(xiàn)原理

實(shí)現(xiàn)原理很簡(jiǎn)單:基于Java正則 + 責(zé)任鏈設(shè)計(jì)模式,按照Curl腳本的常見語(yǔ)法去匹配、解析即可~

按照Curl語(yǔ)法結(jié)構(gòu),可以將其拆分為 5 個(gè)部分:

  • URL路徑:http://cainiao.com
  • URL參數(shù)列表:?param_1=valie_1&param_2=valie_2
  • 請(qǐng)求方法類型: 例如 POST、GET、DELETE、PUT...... 需要正則匹配-X --request等標(biāo)識(shí)符
  • Header請(qǐng)求頭:例如 Cookie、Token、Content-Type...... 需要正則匹配-H --header等標(biāo)識(shí)符
  • Body請(qǐng)求體:可以分為form-data/-form、data-rawdata-urlencode、-d--data、kvbody等。格式可能包含JSON、XML、文本、KV鍵值對(duì),二進(jìn)制流(暫不支持解析)等等。

具體實(shí)現(xiàn)

流程簡(jiǎn)圖:

類關(guān)系圖:

CurlParserUtil

Curl解析工具類:

public class CurlParserUtil {
    /**
     * 該方法是用來解析CURL的入口。
     *
     * @param curl 輸入的CURL文本字符串
     * @return 返回解析后生成的CURL實(shí)體對(duì)象
     */
    public static CurlEntity parse(String curl) {
        CurlEntity entity = CurlEntity.builder().build();
        ICurlHandler<CurlEntity, String> handlerChain = CurlHandlerChain.init();
 
        // 如需擴(kuò)展其他解析器,繼續(xù)往鏈表中add即可
        handlerChain.next(new UrlPathHandler())
                .next(new UrlParamsHandler())
                .next(new HttpMethodHandler())
                .next(new HeaderHandler())
                .next(new HttpBodyHandler());
 
        handlerChain.handle(entity, curl);
        return entity;
    }
}

CurlEntity

解析后得到的Curl實(shí)體類(這里分了5個(gè)部分)

@Data
@Builder
public class CurlEntity {
    /**
     * URL路徑
     */
    private String url;
 
    /**
     * 請(qǐng)求方法類型
     */
    private Method method;
 
    /**
     * URL參數(shù)
     */
    private Map<String, String> urlParams;
 
    /**
     * header參數(shù)
     */
    private Map<String, String> headers;
 
    /**
     * 請(qǐng)求體
     */
    private JSONObject body;
 
    public enum Method {
        GET,
        POST,
        PUT,
        DELETE
    }
}

ICurlHandler

責(zé)任鏈鏈表結(jié)構(gòu)定義:

public interface ICurlHandler<R, S> {
 
    ICurlHandler<CurlEntity, String> next(ICurlHandler<CurlEntity, String> handler);
 
    void handle(CurlEntity entity, String curl);
}

CurlHandlerChain

責(zé)任鏈載體:

public abstract class CurlHandlerChain implements ICurlHandler<CurlEntity, String> {
 
    ICurlHandler<CurlEntity, String> next;
 
    @Override
    public ICurlHandler<CurlEntity, String> next(ICurlHandler<CurlEntity, String> handler) {
        this.next = handler;
        return this.next;
    }
 
    @Override
    public abstract void handle(CurlEntity entity, String curl);
 
    /**
     * for subclass call
     */
    protected void nextHandle(CurlEntity curlEntity, String curl) {
        if (next != null) {
            next.handle(curlEntity, curl);
        }
    }
 
    protected void validate(String curl) {
        if (StringUtils.isBlank(curl)) {
            throw new IllegalArgumentException("Curl script is empty");
        }
 
        Matcher matcher = CURL_BASIC_STRUCTURE_PATTERN.matcher(curl);
        if (!matcher.find()) {
            throw new IllegalArgumentException("Curl script is invalid");
        }
    }
 
    public static CurlHandlerChain init() {
        return new CurlHandlerChain() {
            @Override
            public void handle(CurlEntity entity, String curl) {
                this.validate(curl);
 
                // 替換掉可能存在的轉(zhuǎn)譯(字符串中的空白字符,包括空格、換行符和制表符...)
                curl = curl.replace("\\", "")
                        .replace("\n", "")
                        .replace("\t", "");
 
                if (next != null) {
                    next.handle(entity, curl);
                }
            }
        };
    }
 
    public void log(Object... logParams) {
        // Write log for subclass extensions
    }
}

UrlPathHandler

URL路徑解析:

public class UrlPathHandler extends CurlHandlerChain {
 
    @Override
    public void handle(CurlEntity entity, String curl) {
        String url = parseUrlPath(curl);
        entity.setUrl(url);
 
        this.log(url);
        super.nextHandle(entity, curl);
    }
 
    /**
     * 該方法用于解析URL路徑。
     *
     * @param curl 需要解析的URL,以字符串形式給出
     * @return URL中的路徑部分。如果找不到,將返回null
     */
    private String parseUrlPath(String curl) {
        Matcher matcher = CurlPatternConstants.URL_PATH_PATTERN.matcher(curl);
        if (matcher.find()) {
            return matcher.group(1) != null ? matcher.group(1) : matcher.group(3);
        }
        return null;
    }
 
    @Override
    public void log(Object... logParams) {
        LogPrinter.info("UrlPathHandler execute: url={}", logParams);
    }
}

HttpMethodHandler

請(qǐng)求類型解析:

public class HttpMethodHandler extends CurlHandlerChain {
 
    @Override
    public void handle(CurlEntity entity, String curl) {
        CurlEntity.Method method = parseMethod(curl);
        entity.setMethod(method);
 
        this.log(method);
        super.nextHandle(entity, curl);
    }
 
    private CurlEntity.Method parseMethod(String curl) {
        Matcher matcher = CurlPatternConstants.HTTP_METHOD_PATTERN.matcher(curl);
        Matcher defaultMatcher = CurlPatternConstants.DEFAULT_HTTP_METHOD_PATTERN.matcher(curl);
        if (matcher.find()) {
            String method = matcher.group(1);
            return CurlEntity.Method.valueOf(method.toUpperCase());
        } else if (defaultMatcher.find()) {
            // 如果命令中包含 -d 或 --data,沒有明確請(qǐng)求方法,默認(rèn)為 POST
            return CurlEntity.Method.POST;
        } else {
            // 沒有明確指定請(qǐng)求方法,默認(rèn)為 GET
            return CurlEntity.Method.GET;
        }
    }
 
    @Override
    public void log(Object... logParams) {
        LogPrinter.info("HttpMethodHandler execute: method={}", logParams);
    }
}

UrlParamsHandler

URL參數(shù)列表解析:

public class UrlParamsHandler extends CurlHandlerChain {
 
    @Override
    public void handle(CurlEntity entity, String curl) {
        String url = extractUrl(curl);
        Map<String, String> urlParams = parseUrlParams(url);
        entity.setUrlParams(urlParams);
 
        this.log(urlParams);
        super.nextHandle(entity, curl);
    }
 
    private String extractUrl(String curl) {
        Matcher matcher = CurlPatternConstants.URL_PARAMS_PATTERN.matcher(curl);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return null;
    }
 
    private Map<String, String> parseUrlParams(String url) {
        if (StringUtils.isBlank(url)) {
            return Collections.emptyMap();
        }
 
        Map<String, String> urlParams = new HashMap<>();
        // 提取URL的查詢參數(shù)部分
        String[] urlParts = url.split("\\?");
        if (urlParts.length > 1) {
            // 只處理存在查詢參數(shù)的情況
            String query = urlParts[1];
            // 解析查詢參數(shù)到Map
            String[] pairs = query.split("&");
            for (String pair : pairs) {
                int idx = pair.indexOf("=");
                if (idx != -1 && idx < pair.length() - 1) {
                    String key = pair.substring(0, idx);
                    String value = pair.substring(idx + 1);
                    urlParams.put(key, value);
                } else {
                    // 存在無值的參數(shù)時(shí)
                    urlParams.put(pair, null);
                }
            }
        }
        return urlParams;
    }
 
    @Override
    public void log(Object... logParams) {
        LogPrinter.info("UrlParamsHandler execute: urlParams={}", logParams);
    }
}

HeaderHandler

Http Header解析:

public class HeaderHandler extends CurlHandlerChain{
    
    @Override
    public void handle(CurlEntity entity, String curl) {
        Map<String, String> headers = parseHeaders(curl);
        entity.setHeaders(headers);
 
        this.log(headers);
        super.nextHandle(entity, curl);
    }
 
    private Map<String, String> parseHeaders(String curl) {
        if (StringUtils.isBlank(curl)) {
            return Collections.emptyMap();
        }
 
        Matcher matcher = CurlPatternConstants.CURL_HEADERS_PATTERN.matcher(curl);
        Map<String, String> headers = new HashMap<>();
        while (matcher.find()) {
            String header = matcher.group(1);
            String[] headerKeyValue = header.split(":", 2);
            if (headerKeyValue.length == 2) {
                // 去除鍵和值的首尾空白字符
                headers.put(headerKeyValue[0].trim(), headerKeyValue[1].trim());
            }
        }
 
        return headers;
    }
 
    @Override
    public void log(Object... logParams) {
        LogPrinter.info("HeaderHandler execute: headers={}", logParams);
    }
}

HttpBodyHandler

Request Body請(qǐng)求體解析:

  • form-data/-form
  • data-urlencode
  • data-raw
  • default/-d/--data

格式可能包含JSON、XML、文本、KV鍵值對(duì),二進(jìn)制流(暫不支持解析)等等。

public class HttpBodyHandler extends CurlHandlerChain {
    @Override
    public void handle(CurlEntity entity, String curl) {
        JSONObject body = parseBody(curl);
        entity.setBody(body);
 
        this.log(body);
        super.nextHandle(entity, curl);
    }
 
    private JSONObject parseBody(String curl) {
        Matcher formMatcher = CurlPatternConstants.HTTP_FROM_BODY_PATTERN.matcher(curl);
        if (formMatcher.find()) {
            return parseFormBody(formMatcher);
        }
 
        Matcher urlencodeMatcher = CurlPatternConstants.HTTP_URLENCODE_BODY_PATTERN.matcher(curl);
        if (urlencodeMatcher.find()) {
            return parseUrlEncodeBody(urlencodeMatcher);
        }
 
        Matcher rawMatcher = CurlPatternConstants.HTTP_ROW_BODY_PATTERN.matcher(curl);
        if (rawMatcher.find()) {
            return parseRowBody(rawMatcher);
        }
 
        Matcher defaultMatcher = CurlPatternConstants.DEFAULT_HTTP_BODY_PATTERN.matcher(curl);
        if (defaultMatcher.find()) {
            return parseDefaultBody(defaultMatcher);
        }
 
        return new JSONObject();
    }
 
    private JSONObject parseDefaultBody(Matcher defaultMatcher) {
        String bodyStr = "";
        if (defaultMatcher.group(1) != null) {
            // 單引號(hào)包裹的數(shù)據(jù)
            bodyStr = defaultMatcher.group(1);
        } else if (defaultMatcher.group(2) != null) {
            // 雙引號(hào)包裹的數(shù)據(jù)
            bodyStr = defaultMatcher.group(2);
        } else {
            // 無引號(hào)的數(shù)據(jù)
            bodyStr = defaultMatcher.group(3);
        }
 
        // 判斷是否是json結(jié)構(gòu)
        if (isJSON(bodyStr)) {
            return JSONObject.parseObject(bodyStr);
        }
 
        // 特殊Case: username=test&password=secret
        Matcher kvMatcher = CurlPatternConstants.DEFAULT_HTTP_BODY_PATTERN_KV.matcher(bodyStr);
        return kvMatcher.matches() ? parseKVBody(bodyStr) : new JSONObject();
    }
 
    private JSONObject parseKVBody(String kvBodyStr) {
        JSONObject json = new JSONObject();
        String[] pairs = kvBodyStr.split("&");
        for (String pair : pairs) {
            int idx = pair.indexOf("=");
            String key = URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8);
            String value = URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8);
            json.put(key, value);
        }
        return json;
    }
 
    private JSONObject parseFormBody(Matcher formMatcher) {
        JSONObject formData = new JSONObject();
 
        // 重置指針匹配的位置
        formMatcher.reset();
        while (formMatcher.find()) {
            // 提取表單項(xiàng)
            String formItem = formMatcher.group(1) != null ? formMatcher.group(1) : formMatcher.group(2);
 
            // 分割鍵和值
            String[] keyValue = formItem.split("=", 2);
            if (keyValue.length == 2) {
                String key = keyValue[0];
                String value = keyValue[1];
 
                // 檢測(cè)文件字段標(biāo)記
                // PS: 理論上文件標(biāo)記字段不需要支持
                if (value.startsWith("@")) {
                    // 只提取文件名,不讀取文件內(nèi)容
                    formData.put(key, value.substring(1));
                } else {
                    // 放入表單數(shù)據(jù)
                    formData.put(key, value);
                }
            }
        }
 
        return formData;
    }
 
    private JSONObject parseUrlEncodeBody(Matcher urlencodeMatcher) {
        JSONObject urlEncodeData = new JSONObject();
 
        // 重置指針匹配的位置
        urlencodeMatcher.reset();
        while (urlencodeMatcher.find()) {
            // 提取鍵值對(duì)字符串
            String keyValueEncoded = urlencodeMatcher.group(1);
 
            // 分隔鍵和值
            String[] keyValue = keyValueEncoded.split("=", 2);
            if (keyValue.length == 2) {
                String key = keyValue[0];
                String value = keyValue[1];
 
                // 對(duì)值進(jìn)行URL解碼
                String decodedValue = URLDecoder.decode(value, StandardCharsets.UTF_8);
 
                // 存入數(shù)據(jù)到JSON對(duì)象
                urlEncodeData.put(key, decodedValue);
            }
        }
 
        return urlEncodeData;
    }
 
    private JSONObject parseRowBody(Matcher rowMatcher) {
        String rawData = rowMatcher.group(1);
 
        if (isXML(rawData)) {
            // throw new IllegalArgumentException("Curl --data-raw content cant' be XML");
            return xml2json(rawData);
        }
 
        try {
            return JSON.parseObject(rawData);
        } catch (Exception e) {
            throw new IllegalArgumentException("Curl --data-raw content is not a valid JSON");
        }
    }
 
    private boolean isJSON(String jsonStr) {
        try {
            JSONObject.parseObject(jsonStr);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
 
    public static boolean isXML(String xmlStr) {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setFeature(SecurityConstants.DDD, true);
            factory.setFeature(SecurityConstants.EGE, false);
            factory.setFeature(SecurityConstants.EPE, false);
 
            DocumentBuilder builder = factory.newDocumentBuilder();
            InputSource is = new InputSource(new StringReader(xmlStr));
            builder.parse(is);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
 
    private JSONObject xml2json(String xmlStr) {
        try {
            org.json.JSONObject orgJsonObj = XML.toJSONObject(xmlStr);
            String jsonString = orgJsonObj.toString();
            return JSON.parseObject(jsonString);
        } catch (JSONException e) {
            throw new LinkConsoleException("Curl --data-raw content xml2json error", e);
        }
    }
 
    @Override
    public void log(Object... logParams) {
        LogPrinter.info("HttpBodyHandler execute: body={}", logParams);
    }
}

CurlPatternConstants

正則匹配常量定義:

public interface CurlPatternConstants {
 
    /**
     * CURL基本結(jié)構(gòu)校驗(yàn)
     */
    Pattern CURL_BASIC_STRUCTURE_PATTERN = Pattern.compile("^curl (\\S+)");
 
    /**
     * URL路徑匹配
     */
    Pattern URL_PATH_PATTERN =
            Pattern.compile("(?:\\s|^)(?:'|\")?(https?://[^?\\s'\"]*)(?:\\?[^\\s'\"]*)?(?:'|\")?(?:\\s|$)");
 
    /**
     * 請(qǐng)求參數(shù)列表匹配
     */
    Pattern URL_PARAMS_PATTERN = Pattern.compile("(?:\\s|^)(?:'|\")?(https?://[^\\s'\"]+)(?:'|\")?(?:\\s|$)");
 
    /**
     * HTTP請(qǐng)求方法匹配
     */
    //Pattern HTTP_METHOD_PATTERN = Pattern.compile("(?:-X|--request)\\s+(\\S+)");
    Pattern HTTP_METHOD_PATTERN = Pattern.compile("curl\\s+[^\\s]*\\s+(?:-X|--request)\\s+'?(GET|POST)'?");
 
    /**
     * 默認(rèn)HTTP請(qǐng)求方法匹配
     */
    Pattern DEFAULT_HTTP_METHOD_PATTERN = Pattern.compile(".*\\s(-d|--data|--data-binary)\\s.*");
 
    /**
     * 請(qǐng)求頭匹配
     */
    Pattern CURL_HEADERS_PATTERN = Pattern.compile("(?:-H|--header)\\s+'(.*?:.*?)'");
 
    /**
     * -d/--data 請(qǐng)求體匹配
     */
    Pattern DEFAULT_HTTP_BODY_PATTERN = Pattern.compile("(?:--data|-d)\\s+(?:'([^']*)'|\"([^\"]*)\"|(\\S+))", Pattern.DOTALL);
    Pattern DEFAULT_HTTP_BODY_PATTERN_KV = Pattern.compile("^([^=&]+=[^=&]+)(?:&[^=&]+=[^=&]+)*$", Pattern.DOTALL);
 
    /**
     * --data-raw 請(qǐng)求體匹配
     */
    Pattern HTTP_ROW_BODY_PATTERN = Pattern.compile("--data-raw '(.+?)'(?s)", Pattern.DOTALL);
 
    /**
     * --form 請(qǐng)求體匹配
     */
    Pattern HTTP_FROM_BODY_PATTERN = Pattern.compile("--form\\s+'(.*?)'|-F\\s+'(.*?)'");
 
 
    /**
     * --data-urlencode 請(qǐng)求體匹配
     */
    Pattern HTTP_URLENCODE_BODY_PATTERN = Pattern.compile("--data-urlencode\\s+'(.*?)'");
 
}

其他代碼

public class SecurityConstants {
    public static String DDD = "http://apache.org/xml/features/disallow-doctype-decl";
    public static String EGE = "http://xml.org/sax/features/external-general-entities";
    public static String EPE = "http://xml.org/sax/features/external-parameter-entities";
    public static String LED = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
}

以上就是使用Java實(shí)現(xiàn)一個(gè)解析CURL腳本小工具的詳細(xì)內(nèi)容,更多關(guān)于Java實(shí)現(xiàn)解析CURL工具的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue結(jié)合Springboot實(shí)現(xiàn)用戶列表單頁(yè)面(前后端分離)

    Vue結(jié)合Springboot實(shí)現(xiàn)用戶列表單頁(yè)面(前后端分離)

    本文主要介紹了Vue結(jié)合Springboot實(shí)現(xiàn)用戶列表單頁(yè)面,可以實(shí)現(xiàn)簡(jiǎn)單的查詢,刪除,修改,和添加用戶信息功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Java導(dǎo)出txt文件的方法

    Java導(dǎo)出txt文件的方法

    這篇文章主要介紹了Java導(dǎo)出txt文件的方法,實(shí)例分析了兩種java導(dǎo)出txt文本文件的使用技巧,需要的朋友可以參考下
    2015-05-05
  • 淺談Timer和TimerTask與線程的關(guān)系

    淺談Timer和TimerTask與線程的關(guān)系

    下面小編就為大家?guī)硪黄獪\談Timer和TimerTask與線程的關(guān)系。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • logback-spring.xml的內(nèi)容格式詳解

    logback-spring.xml的內(nèi)容格式詳解

    這篇文章主要介紹了logback-spring.xml的內(nèi)容格式詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的的朋友參考下吧
    2023-11-11
  • SpringBoot優(yōu)化接口響應(yīng)時(shí)間的九個(gè)技巧

    SpringBoot優(yōu)化接口響應(yīng)時(shí)間的九個(gè)技巧

    在實(shí)際開發(fā)中,提升接口響應(yīng)速度是一件挺重要的事,特別是在面臨大量用戶請(qǐng)求的時(shí)候,本文為大家整理了9個(gè)SpringBoot優(yōu)化接口響應(yīng)時(shí)間的技巧,希望對(duì)大家有所幫助
    2024-01-01
  • SpringBoot系列教程JPA之基礎(chǔ)環(huán)境搭建的方法

    SpringBoot系列教程JPA之基礎(chǔ)環(huán)境搭建的方法

    這篇文章主要介紹了SpringBoot系列教程JPA之基礎(chǔ)環(huán)境搭建的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Spring?boot整合ELK詳細(xì)過程

    Spring?boot整合ELK詳細(xì)過程

    ELK是由Elasticsearch、Logstash和Kibana三個(gè)開源軟件組成的技術(shù)堆棧,主要用于數(shù)據(jù)的存儲(chǔ)、處理和可視化,本文給大家介紹Spring?boot整合ELK詳細(xì)過程,感興趣的朋友一起看看吧
    2024-01-01
  • idea maven項(xiàng)目無法識(shí)別jar包里的class解決方案

    idea maven項(xiàng)目無法識(shí)別jar包里的class解決方案

    這篇文章主要介紹了idea maven項(xiàng)目無法識(shí)別jar包里的class解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • java?Springboot對(duì)接開發(fā)微信支付詳細(xì)流程

    java?Springboot對(duì)接開發(fā)微信支付詳細(xì)流程

    最近要做一個(gè)微信小程序,需要微信支付,所以研究了下怎么在java上集成微信支付功能,下面這篇文章主要給大家介紹了關(guān)于java?Springboot對(duì)接開發(fā)微信支付的相關(guān)資料,需要的朋友可以參考下
    2024-08-08
  • Java并發(fā)編程之線程間的通信

    Java并發(fā)編程之線程間的通信

    當(dāng)線程在系統(tǒng)內(nèi)運(yùn)行時(shí),程序通常無法準(zhǔn)確的控制線程的輪換執(zhí)行,但我們可以通過一些機(jī)制來保障線程的協(xié)調(diào)運(yùn)行,本文著重講解線程間的通信機(jī)制
    2021-06-06

最新評(píng)論

滦平县| 贵州省| 子洲县| 巴里| 白银市| 安龙县| 天长市| 邯郸县| 陵水| 宣武区| 贺州市| 宁国市| 乐山市| 呼和浩特市| 张掖市| 包头市| 忻城县| 湘潭县| 临漳县| 枣庄市| 古交市| 玉门市| 新民市| 佳木斯市| 安西县| 小金县| 中超| 通州市| 阿拉善盟| 中超| 自治县| 江油市| 铁岭市| 邢台市| 宜宾县| 金溪县| 长宁县| 阳东县| 偃师市| 新建县| 云南省|