1. 程式人生 > >Map資料在多執行緒 情況下出現的問題

Map資料在多執行緒 情況下出現的問題

公司去年 就接入了  神策大資料分析,去年埋點一直問題不斷 修修補補,  一年的續費快完了,大佬說 今年用完了 就不用了,沒什麼卵用,就是報表做的好看 .....


去年在 做埋點的時候 遇到不少坑,今年 修復的時候也踩map的 坑

是這樣的 .我們的埋點會向神策資料分析伺服器提交資料,神策java sdk提交資料函式是

sa.track(distinctId, isLoginId, eventName, newMap);

我們隊這個函式進行了封裝

變成上圖的樣子一開始 是沒有配置 pool 執行緒池的 就是單執行緒,上線使用後會發現 特殊情況下   商城業務處理完之後 觸發了神策埋點 ,資料原因導致空指標  ,伺服器報錯後用戶的頁面就 500了 ,跳轉到業務也執行不到了,於是 加入了多執行緒 處理  ,一加不要緊,暴露出了幾個問題

第一個問題 : 

senSors(....);函式中有個map 引數,埋點處直接觸發後 map 會出現多執行緒複用的錯誤


於是  我定義在senSor函式中 加了一個Map  new    Map = '傳進來的引數map';

啟動沒有報錯 萬事大吉  提交上線!!

過了 差不多半個月...產品經理 輕輕喊了我一聲,我知道大事不好  一定出問題了

果然  一個完美bug  出現在我眼前

在senSor函式中 重新將map 賦值給另一個 新變數 是能繞過 多執行緒複用問題  畢竟 每條執行緒拿到的map都是 一個新物件

但是萬惡的  業務程式碼中  有一個 map.clear 的呼叫,也就是說  在新開啟一條執行緒的一瞬間  主執行緒是自己已經去執行  map.clear 程式碼去了,但是 新執行緒中傳入的新物件 newMap  的記憶體地址 還是和 被clear的物件是一樣的...........所以 senSor 函式僅僅提交了一個事件  引數map中 連毛都沒有一根

機智的 我馬上想到了 map 的clone 函式  ,於是我按下了.  打了一個c  智慧提示中並沒有clone函式....操 怎麼這麼奇怪  ,

沒錯 map只是一個藉口  clone 是HashMap這個實現類的 函式,於是 senSors(..)函式中定義 Map<string,object> map

修改為 HashMap 型別 .....等等

senSors(...)函式是定義在工具類專案中的   ,我們公司 各個分支的程式碼都是引用這個util的.在util中改東西是作死的

於是,我在模擬環境的版本中這樣修復了bug

wap  app  web就三個專案 有使用到 senSors()函式,沒錯我們公司 有兩套 wap app web 專案,因為有苟延殘喘的一折購,和精力旺盛的一折吃兩個專案版本  是拆分開的.......於是只能留下沒有技術的眼淚   按住ctrl 點選senSors()函式  查詢6個專案中 每一處埋點...手動修改 (HashMap<string,object>) map.clone()  ;

修改  提交程式碼,模擬環境重啟.....   開啟log   買個東西  又提交資料 ok 寫完了

別問為什麼寫完了..手疼

相關推薦

Map資料執行 情況出現的問題

公司去年 就接入了  神策大資料分析,去年埋點一直問題不斷 修修補補,  一年的續費快完了,大佬說 今年用完了 就不用了,沒什麼卵用,就是報表做的好看 .....去年在 做埋點的時候 遇到不少坑,今年 修復的時候也踩map的 坑是這樣的 .我們的埋點會向神策資料分析伺服器提交

關於在執行情況同步爬蟲爬取結果的一個例子

這些天一直在用java做爬蟲工作,之前遇到的都比較簡單,大多都是單介面的爬取,這次需要爬蟲100多個介面,肯定得多跑幾個執行緒 然而這些介面由於資訊中有重複,leader要求我們必須去重,因為資料庫更改是有次數限制的。所以搞了幾天,才把這個程式寫出來。 先寫一下思想:首先,利用JA

設計模式之單例模式(餓漢式+執行情況的懶漢式單例)

  今天所記錄的補上昨天未完成的設計模式之單例模式 餓漢式單例:    執行結果:    在編寫餓漢式單例時使用了final 關鍵字進行修飾所以不會出現多執行緒安全的情況產生。接下來我們完善一下昨天的懶漢式單例:   首先我們看一下昨天懶漢式單例的執行圖:        發現

智慧指標在執行情況的問題

這兩天在測試一個程式的時候發現,一旦壓力達到一定程度,程式立即就會崩潰,報的錯誤幾乎都在new的時候沒有記憶體了,一開始以為確實是因為記憶體分配的問題,後來在程式執行過程中用top觀察,發現記憶體使用很低,因此可以確認不應該是瞬間記憶體使用完造成的。因此認真看了一下core

執行情況慎用localtime_r

最近有個需求,需要提升日誌模組的效能。當前日誌模組每秒鐘處理的日誌數量大概在55w左右,於是進行優化,在日誌的IO執行緒中將sprintf剝離,提前將時間、日誌等級等格式化處理。 於是這樣就產生了一個問題,在IO執行緒中頻繁的使用localtime_r來獲取日期時間,在單執

執行情況,單例模式的實現方式

方式1(推薦)package singleton; public class Singletion { private static class InnerSingletion { priv

執行情況,主執行先退出,子執行會被強制退出嗎

1、程序中執行緒之間的關係 執行緒不像程序,一個程序中的執行緒之間是沒有父子之分的,都是平級關係。即執行緒都是一樣的, 退出了一個不會影響另外一個。 但是所謂的"主執行緒"main,其入口程式碼是類似這樣的方式呼叫main的:exit(main(...))。 main執行完

(轉載)執行環境Map一定要同步嗎?

原文地址:http://pt.alibaba-inc.com/wp/experience_644/map-multi-threaded-environment-you-must-be-synchronized.html 我們都知道在多執行緒操縱Map時,需要對Map資料結構

HashMap執行環境的死迴圈問題解釋

hashMap在多執行緒環境下,呼叫put方法出現的死迴圈是由於擴容時候resize方法導致的連結串列出現迴圈。 void resize(int newCapacity) { Entry[] oldTable = table; int oldCapacity =

基於Log4j NDC 執行條件記錄日誌,排查生產問題

在大吞吐,高併發的場景, 一個請求到達後端,通常是轉換成多執行緒並行處理請求, 如何通過一個標誌找到這個請求對應的多個執行緒,瞭解這個請求的完整的處理情況,從而幫助我們定位這次呼叫到底哪一步出現了問題,對我們快速定位排查生產問題是非常有用的。我們在每個子任務程式

java day25 執行) 單例類(Runtime,Timer

25.01_多執行緒(單例設計模式)(掌握) 單例設計模式:保證類在記憶體中只有一個物件。 如何保證類在記憶體中只有一個物件呢? (1)控制類的建立,不讓其他類來建立本類的物件。private (2)在本類中定義一個本類的物件。Singl

halcon 外部函式如:disp_message()等外部函式在遇到個hv_ExpDefaultWinHandle情況出現呼叫不正常/錯誤的情況

最近在做有關工業相機的手眼標定的專案,在HALCON中匯出了相機標定的C#格式程式碼,所用到的halcon例項名稱為:calibrate_cameras_monocular.cs。 想實現標定影象和對應的3D場景分別顯示在一個halconwindow中,如下圖所示:

Java執行環境的懶漢模式解決方案

一、場景簡述 單例模式下有餓漢模式和懶漢模式,其中懶漢模式在於呼叫相關方法時例項才被建立。懶漢模式我們不難實現,但是在懶漢模式下我們如果使用多執行緒,就會取出多個例項的情況,與單例模式相違背,所以該篇部落格筆者主要關於在多執行緒環境下利用DCL雙檢查鎖機制來實現懶漢模式。

linux執行環境的搶屍行為(system返回-1:No child processes)

#!/usr/bin/env python #coding:utf8 import os import time pid = os.fork() if pid: print 'in parent.sleepin....' while True:

執行環境呼叫 HttpWebRequest 併發連線限制

.net 的 HttpWebRequest 或者 WebClient 在多執行緒情況下存在併發連線限制,這個限制在桌面作業系統如 windows xp , windows  7 下預設是2,在伺服器作業系統上預設為10. 如果不修改這個併發連線限制,那麼客戶端同時可以建立的

執行環境的ConcurrentHashMap

文章目錄 什麼是ConcurrentHashMap? 底層資料結構? 如何實現併發安全? transfer和ForwardingNode Hash計算 什麼是ConcurrentHashMap? C

執行環境使用log4j輸出各執行的標識,區分各執行輸出的內容

在多執行緒環境下,我們可能需要輸出很多資訊,每個執行緒產生的日誌資訊可能都是類似的,我們如何區分出哪些資訊是同一個執行緒輸出的呢?其實log4j已經提供了多種實現方式: 1.使用PatternLayout,在設定輸出格式的時候增加%t引數,這樣會輸出各個執行緒的執行緒名稱,這樣我們就可以根據執行緒名稱區分哪

執行之futureTask(future,callable)例項,jdbc資料執行查詢

最近遇到一個這樣的功能要求。在查詢資料時,由於查詢的資料量比較大,一次查詢(一條SQL語句中包含太多的條件)查詢起來很慢,大約要10S左右才能查詢出來,這樣體驗太不好了,需要進行優化。今天想了想,打算採用在後端把一條SQL進行拆分,拆分成為多條SQL語句,再拋給多個執行緒去

從專案中談JAVA中static 方法在執行環境的運用

最近在做一個實時性比較高的系統,資料庫訪問很頻繁。在這個專案中資料庫訪問的大多數都被我做成了static 方法。(這樣做應該不是很好,沒辦法發揮dao模式的優勢,不過湊合用吧)因這個系統是多執行緒。static方法的運用需要注意,不能在servlet中使用成員變數,因為如果你

執行併發的單例模式實現

1.1 天生執行緒安全的餓漢式單例 1.2 懶漢式單例 1.2.1 執行緒不安全的懶漢式單例 1.2.2 執行緒安全的懶漢式單例