生產問題: 利用線程Thread預加載數據緩存偶發加載不到
先上代碼
public class ThreadTest {//本地緩存Map<String, Object> map = new HashMap<String, Object>();class ThreadA implements Runnable{@Overridepublic void run() {System.out.println("ThreadA");initCache();}}//加載緩存void initCache(){for (int i = 0; i < 5; i++) {map.put(String.valueOf(i),i);}}void ThreadTestStart(){for (int i = 0; i < 10; i++) {Thread threadA = new Thread(new ThreadA());threadA.setName("threadA"+i);//threadA.setPriority(10);//設置優先級threadA.start();System.out.println(threadA.getName());}}void getCacheByKey(String key){Object value = map.get(key);System.out.println("key:"+key+"-value:"+value);}public static void main(String[] args) {try {ThreadTest threadTest = new ThreadTest();threadTest.ThreadTestStart();//Thread.sleep(500);//睡眠500毫秒等待可以拿到數據threadTest.getCacheByKey("1");} catch (Exception e) {e.printStackTrace();}}
}
利用線程去加載緩存的時候, 線程start() 不一定立即執行, 要等分配時間片,
線程啟動后,在這個時候去獲取數據時會拿不到數據
睡眠一下
本人在生產的場景是這樣子的(一個運行了十年的老項目)
一個bean實現了 BeanPostProcessor 接口,重寫 postProcessAfterInitialization() 方法來加載緩存 initCache , 這個加載方法是新建了一個線程Thread 并啟動start() , 這個本地緩存在Controller的全局變量中獲取使用, 導致啟動項目時會偶發報錯 ( 取決于加載緩存的線程能不能拿到時間片去執行run()方法從而加載緩存 ) , 可能是這個線程的優先級不高, 然后就設置了優先級為最大 setPriority(10) , 默認的優先級是5