眾所周知,通過唯一的鏈路id來追蹤一次請求的所有日志,對于排查生產問題來說,會是非常給力的,
這個比較容易實作,我之前的博客也有多次提及,
那么,如果涉及到異步執行緒處理的話,我們知道,由于異步執行緒與作業執行緒是兩個不同的執行緒,因此,這時的執行緒名會發生變化,一次請求的完整日志就無法通過唯一的標識來過濾了,
有沒有辦法呢?
問題即答案,當然是有的,
執行緒是用來執行任務的,任務是一段程式代碼的封裝,在java中,任務通過 java.lang.Runnable 來表示,使用方面,我們可以自己定義一個實作Runnable的任務類,也可以用lambda運算式的方式直接使用Runnable,來作為執行緒或執行緒池的引數,
自定義實作了Runnable的類來使用異步執行緒,先貼demo代碼,
實作了Runnable介面的類--MyTask:
package com.emaxcard.test; import lombok.extern.slf4j.Slf4j; @Slf4j public class MyTask implements Runnable { String flag; public MyTask(String flag) { this.flag = flag; } @Override public void run() { log.info("這是異步執行緒里的日志,引數flag={}", flag); } }View Code
主執行緒測驗類:
package com.emaxcard.test; import lombok.extern.slf4j.Slf4j; @Slf4j public class RunnableTest { public static void main(String[] args) { log.info("主執行緒begin"); new Thread(new MyTask("引數值test")).start(); log.info("主執行緒end"); } }View Code
列印出來的log如下:
16:11:27.613 [main] INFO com.emaxcard.test.RunnableTest - 主執行緒begin
16:11:27.629 [main] INFO com.emaxcard.test.RunnableTest - 主執行緒end
16:11:27.630 [Thread-0] INFO com.emaxcard.test.MyTask - 這是異步執行緒里的日志,引數flag=引數值test
我們希望看到的日志是:
16:11:27.613 [main] INFO com.emaxcard.test.RunnableTest - 主執行緒begin
16:11:27.629 [main] INFO com.emaxcard.test.RunnableTest - 主執行緒end
16:11:27.630 [main] INFO com.emaxcard.test.MyTask - 這是異步執行緒里的日志,引數flag=引數值test
小支一招,輕松搞定,給 MyTask 加點料,代碼如下,這樣就能實作?是的,因為構造MyTask物件的操作發生在當前作業執行緒,也就是說,MyTask構造器的代碼是在作業執行緒里執行的,沒錯,正是基于這一點,
package com.emaxcard.test; import lombok.extern.slf4j.Slf4j; @Slf4j public class MyTask implements Runnable { String flag; String threadName; public MyTask(String flag) { this.flag = flag; this.threadName = Thread.currentThread().getName(); } @Override public void run() { Thread.currentThread().setName(threadName); log.info("這是異步執行緒里的日志,引數flag={}", flag); } }
同樣,用lambda運算式使用Runnable來使用異步執行緒,傳遞執行緒名,也很簡單,貼出來上面的 RunnableTest 的代碼,
package com.emaxcard.test; import lombok.extern.slf4j.Slf4j; @Slf4j public class RunnableTest { public static void main(String[] args) { log.info("主執行緒begin"); String name = Thread.currentThread().getName(); new Thread(new Runnable() { @Override public void run() { Thread.currentThread().setName(name); log.info("這是異步執行緒里的日志"); } }).start(); log.info("主執行緒end"); } }
當看到一些不好的代碼時,會發現我還算優秀;當看到優秀的代碼時,也才意識到持續學習的重要!--buguge
本文來自博客園,轉載請注明原文鏈接:https://www.cnblogs.com/buguge/p/16616927.html
<style>hr.signhr{width:80%;margin:0 auto;border: 0;height: 4px;background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0))}</style>
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/502556.html
標籤:其他
