ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 10, 100, TimeUnit.MINUTES, new ArrayBlockingQueue<>(1000)); threadPoolExecutor.execute(() -> System.out.println("print in thread"));
"Thread" -> "BlockingQueue": pool task "Thread" -> "BlockingQueue": get global ReentrantLock alt get global ReentrantLock success alt BlockingQueue size = 0 "Thread" -> "Condition": await keepAliveTime "BlockingQueue" -> "Thread": non task,execute processWorkerExit method else "BlockingQueue" -> "Thread": first task in queue "Thread" -> "Thread": keep execute task end else "Thread" -> "BlockingQueue": keep acquire ReentrantLock end @enduml
@startuml Database Database as DB entity Cache as Cache
query -> repository: select data
repository -> cache: get data repository -> DB: get data DB -> repository: return data repository -> cache: update data repository -> query: return data
@enduml
wirte though
1 2 3 4 5 6 7 8 9 10 11 12
@startuml Database Database as DB entity Cache as Cache
transcation -> repository: update data
repository -> cache: update data repository -> DB: update data DB -> repository: return result repository -> transcation: return result
@enduml
可能出现的数据不一致
程序没有优雅关闭,更新请求先更新了缓存,但还没更新数据库,数据丢失
更新缓存成功,更新数据库失败导致的数据不一致
适用场景
更新数据库极低概率失败
程序有优雅关闭功能
改进方式
暂无
Write Behind
1 2 3 4 5 6 7 8 9 10 11 12 13 14
@startuml Database Database as DB entity Cache as Cache
query -> repository: query data
repository -> cache: query data repository -> DB: query data DB -> repository: return data repository -> cache: update data
repository -> query: return data
@enduml
1 2 3 4 5 6 7 8 9 10 11
@startuml Database Database as DB entity Cache as Cache
@Override public T getData(K key){ //get data from cache TdataFromCache= cacheUpdate.getData(key); //if cache haven't, get from database and put to cache if(Objects.nonNull(dataFromCache)){ return dataFromCache; } TdataFromDatabase= databaseOperation.getData(key); cacheUpdate.addData(key, dataFromDatabase); return dataFromDatabase; }
@Override publicbooleanupdateData(K key, T data){ //update data to database booleanupdateToDatabaseRes= databaseOperation.updateData(key, data); if(updateToDatabaseRes){ //invalid cache data return cacheUpdate.removeData(key); } returnfalse; }
@Override publicbooleanaddData(K key, T data){ //add data to database return databaseOperation.addData(key, data); }
@Override publicbooleanremoveData(K key){ //remove from database booleanremoveFromDatabaseRes= databaseOperation.removeData(key); if(removeFromDatabaseRes){ //invalid cache data return cacheUpdate.removeData(key); } returnfalse; }
@Override public T getData(K key) { //if cache has data, return if(map.containsKey(key)){ return map.get(key); } //get data from database and write to cache Tdata= databaseOperation.getData(key); map.put(key, data); return data; }