javamap緩存
/**
*緩存池
*@authorxiaoquan
*@create2015年3月13日上午10:32:13
*@see
*/
publicclassCachePool{
;//緩存池唯一實例
privatestaticMap<String,Object>cacheItems;//緩存Map
privateCachePool(){
cacheItems=newHashMap<String,Object>();
}
/**
*得到唯一實例
*@return
*/
(){
if(instance==null){
instance=newCachePool();
}
returninstance;
}
/**
*清除所有Item緩存
*/
(){
cacheItems.clear();
}
/**
*獲取緩存實體
*@paramname
*@return
*/
(Stringname){
if(!cacheItems.containsKey(name)){
returnnull;
}
CacheItemcacheItem=(CacheItem)cacheItems.get(name);
if(cacheItem.isExpired()){
returnnull;
}
returncacheItem.getEntity();
}
/**
*存放緩存信息
*@paramname
*@paramobj
*@paramexpires
*/
(Stringname,Objectobj,longexpires){
if(!cacheItems.containsKey(name)){
cacheItems.put(name,newCacheItem(obj,expires));
}
CacheItemcacheItem=(CacheItem)cacheItems.get(name);
cacheItem.setCreateTime(newDate());
cacheItem.setEntity(obj);
cacheItem.setExpireTime(expires);
}
(Stringname,Objectobj){
putCacheItem(name,obj,-1);
}
/**
*移除緩存數據
*@paramname
*/
(Stringname){
if(!cacheItems.containsKey(name)){
return;
}
cacheItems.remove(name);
}
/**
*獲取緩存數據的數量
*@return
*/
publicintgetSize(){
returncacheItems.size();
}
}
publicclassCacheItem{
privateDatecreateTime=newDate();//創建緩存的時間
privatelongexpireTime=1;//緩存期滿的時間
privateObjectentity;//緩存的實體
publicCacheItem(Objectobj,longexpires){
this.entity=obj;
this.expireTime=expires;
}
publicbooleanisExpired(){
return(expireTime!=-1&&newDate().getTime()-createTime.getTime()>expireTime);
}
/**
*省略getter、setter方法
*/
}
2. 使用java實現以個簡單的緩存機制
你這個分數太少了吧,程序到是有,不過給你有點可惜
CacheMgr.java
import java.util.*;
import cn.javass.framework.cache.vo.CacheConfModel;
public class CacheMgr {
private static Map cacheMap = new HashMap();
private static Map cacheConfMap = new HashMap();
private CacheMgr(){
}
private static CacheMgr cm = null;
public static CacheMgr getInstance(){
if(cm==null){
cm = new CacheMgr();
Thread t = new ClearCache();
t.start();
}
return cm;
}
/**
* 增加緩存
* @param key
* @param value
* @param ccm 緩存對象
* @return
*/
public boolean addCache(Object key,Object value,CacheConfModel ccm){
boolean flag = false;
cacheMap.put(key, value);
cacheConfMap.put(key, ccm);
System.out.println("now addcache=="+cacheMap.size());
return true;
}
/**
* 刪除緩存
* @param key
* @return
*/
public boolean removeCache(Object key){
cacheMap.remove(key);
cacheConfMap.remove(key);
System.out.println("now removeCache=="+cacheMap.size());
return true;
}
/**
* 清除緩存的類
* @author wanglj
* 繼承Thread線程類
*/
private static class ClearCache extends Thread{
public void run(){
while(true){
Set tempSet = new HashSet();
Set set = cacheConfMap.keySet();
Iterator it = set.iterator();
while(it.hasNext()){
Object key = it.next();
CacheConfModel ccm = (CacheConfModel)cacheConfMap.get(key);
//比較是否需要清除
if(!ccm.isForever()){
if((new Date().getTime()-ccm.getBeginTime())>= ccm.getDurableTime()*60*1000){
//可以清除,先記錄下來
tempSet.add(key);
}
}
}
//真正清除
Iterator tempIt = tempSet.iterator();
while(tempIt.hasNext()){
Object key = tempIt.next();
cacheMap.remove(key);
cacheConfMap.remove(key);
}
System.out.println("now thread================>"+cacheMap.size());
//休息
try {
Thread.sleep(60*1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
CacheConfModel.java
public class CacheConfModel implements java.io.Serializable{
private long beginTime;
private boolean isForever = false;
private int rableTime;
public long getBeginTime() {
return beginTime;
}
public void setBeginTime(long beginTime) {
this.beginTime = beginTime;
}
public boolean isForever() {
return isForever;
}
public void setForever(boolean isForever) {
this.isForever = isForever;
}
public int getDurableTime() {
return rableTime;
}
public void setDurableTime(int rableTime) {
this.rableTime = rableTime;
}
}
順便說一句,緩存的管理不是靠時間久來計算的,是靠最大不活動間隔計算的,你的設計思想有問題
3. java中怎麼樣將方法中的map內數據保存以便在下次調用時繼續使用
你可以把這個map定義為類成員,如果是通過靜態方法向map裡面加東西,那就定義為靜態成員。總之,定義為方法內的局部變數是肯定不行的,因為它的作用域是方法內,執行一次方法後,這個map變數的生命周期就到了,下次再調用的時候,是產生一個新的map。(java不像c,c++,沒有局部靜態變數)
4. java map可以放多少數據
map由key value鍵值對組成,具體放多少數據和你的伺服器運行時的內存有關系,同時也和你代碼中及時清理無效緩存有關系。
一般編寫代碼中不會去考慮放多少數據問題,除非你數據量超級大對內存要求比較高。這個時候需要對代碼和伺服器進行優化
5. 請教java中怎麼緩存大量的數據,比如100w條記錄
通常Java的緩存都是用HashMap,數據大的話,佔用內存就大,所以JVM虛擬機在啟動的時候要把內存設置大點,否則會內存溢出。
Java學習交流!
6. java下載圖片出錯使用map集合緩存地址怎麼寫
理論上,jvm會定期幫你回收垃圾,釋放內存。 如果短時間大量調用該方法,建議用System.gc(),強制回收,jvm會較快響應(非及時)。
另外, refreshData 需要謹慎,不用的對象盡量賦值null,方便回收
7. 為什麼Java的Hashmap比Python的dictionary慢得多
如果按照題主給出的Java和Python代碼,在常見環境里按照默認配置來跑測試,確實會發現Python版例子比Java版例子跑得快。這自然也算是Java性能的一個坑啦——從來就沒有什麼「理論上Java應該比Python快」的理論,而是在知道常見性能坑、知道best practice的前提下,純Java程序在較大規模的運算上有可能比純Python程序有更好的性能,並且相對來說更scalable。
話說回來,這個例子要讓Java比Python跑得快無需修改代碼,只要稍微修改一下Java的啟動參數即可。另外我也相信這個小例子不一定充分反映了題主說的「需要3個小時以上」的那個Java程序的性能問題。那個程序或許也只需要稍微調整一下啟動參數就可以大幅提高性能,也可能要修改代碼去掉一些不好的做法。
所以具體到題主這個例子,是什麼造成Java比Python慢得多?是HashMap寫得沒dict好?是因為HashMap用Java實現而dict用C實現?是因為JIT的預熱開銷?還是別的?
假定題主運行Java和Python的環境都是常見的,例如說Oracle JDK vs 原裝CPython,那麼在Java一側討論的對象就是Oracle JDK里的HotSpot VM的性能。
答案是:是因為題主沒有設置好GC的參數,而HotSpot VM默認的GC參數在這個例子上非常不適用,導致默認參數下Java版的性能非常糟糕。Java的HashMap自身並不慢,特別是經過JIT編譯後它其實不會比CPython的dict慢,至少不是造成這個例子的性能差異的原因。
8. java static map 靜態的集合類型變數(大數據)多次重復賦值對內存佔用會產生什麼樣的影響
這種做法是個不好做法。
可以:1 實用緩存組件 如OSCache 之類
2 如果不用緩存組件 ,可以使用軟引用,來使JVM能正常釋放內存。
9. java jdis 可以緩存map 嗎
緩存是Java中主要的內容,主要目的是緩解項目訪問資料庫的壓力以及提升訪問數據的效率,以下是通過Map實現java緩存的功能,並沒有用cache相關框架。
一、緩存管理類 CacheMgr.java
[java] view plain
package cache.com;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* 緩存管理類
* @author Administrator
*
*/
public class CacheMgr {
private static Map cacheMap = new HashMap();
private static Map cacheConfMap = new HashMap();
private static CacheMgr cm = null;
//構造方法
private CacheMgr(){
}
public static CacheMgr getInstance(){
if(cm==null){
cm = new CacheMgr();
Thread t = new ClearCache();
t.start();
}
return cm;
}
/**
* 增加緩存
* @param key
* @param value
* @param ccm 緩存對象
* @return
*/
public boolean addCache(Object key,Object value,CacheConfModel ccm){
System.out.println("開始增加緩存-------------");
boolean flag = false;
try {
cacheMap.put(key, value);
cacheConfMap.put(key, ccm);
System.out.println("增加緩存結束-------------");
System.out.println("now addcache=="+cacheMap.size());
flag=true;
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
* 獲取緩存實體
*/
public Object getValue(String key){
Object ob=cacheMap.get(key);
if(ob!=null){
return ob;
}else{
return null;
}
}
/**
* 獲取緩存數據的數量
* @return
*/
public int getSize(){
return cacheMap.size();
}
/**
* 刪除緩存
* @param key
* @return
*/
public boolean removeCache(Object key){
boolean flag=false;
try {
cacheMap.remove(key);
cacheConfMap.remove(key);
flag=true;
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
* 清除緩存的類
* 繼承Thread線程類
*/
private static class ClearCache extends Thread{
public void run(){
while(true){
Set tempSet = new HashSet();
Set set = cacheConfMap.keySet();
Iterator it = set.iterator();
while(it.hasNext()){
Object key = it.next();
CacheConfModel ccm = (CacheConfModel)cacheConfMap.get(key);
//比較是否需要清除
if(!ccm.isForever()){
if((new Date().getTime()-ccm.getBeginTime())>= ccm.getDurableTime()*60*1000){
//可以清除,先記錄下來
tempSet.add(key);
}
}
}
//真正清除
Iterator tempIt = tempSet.iterator();
while(tempIt.hasNext()){
Object key = tempIt.next();
cacheMap.remove(key);
cacheConfMap.remove(key);
}
System.out.println("now thread================>"+cacheMap.size());
//休息
try {
Thread.sleep(60*1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
二、緩存屬性類 CacheConfModel.java
[java] view plain
package cache.com;
/**
* 緩存屬性類
* @author Administrator
*
*/
public class CacheConfModel implements java.io.Serializable{
private long beginTime;//緩存開始時間
private boolean isForever = false;//是否持久
private int rableTime;//持續時間
public long getBeginTime() {
return beginTime;
}
public void setBeginTime(long beginTime) {
this.beginTime = beginTime;
}
public boolean isForever() {
return isForever;
}
public void setForever(boolean isForever) {
this.isForever = isForever;
}
public int getDurableTime() {
return rableTime;
}
public void setDurableTime(int rableTime) {
this.rableTime = rableTime;
}
}
10. java語言如何設置Map中一個鍵值對的生命周期
通常來說,Map是一個由鍵值對組成的數據結構,且在集合中每個鍵是唯一的。下面就以K和V來代表鍵和值,來說明一下java中關於Map的九大問題。
0、將Map轉換為List類型
在java中Map介面提供了三種集合獲取方式:Key set,,value set, and key-value set.。它們都可以通過構造方法或者addAll()方法來轉換為List類型。下面代碼就說明了如何從Map中構造ArrayList:
// key list
List keyList = new ArrayList(map.keySet());
// value list
List valueList = new ArrayList(map.valueSet());
// key-value list
List entryList = new ArrayList(map.entrySet());
1、通過Entry 遍歷Map
java中這種以鍵值對存在的方式被稱為Map.Entry。Map.entrySet()返回的是一個key-value 集合,這是一種非常高效的遍歷方式。
for(Entry entry: map.entrySet()) {
// get key
K key = entry.getKey();
// get value
V value = entry.getValue();
}
Iterator 我們也經常用到,尤其是在JDK1.5以前
Iterator itr = map.entrySet().iterator();
while(itr.hasNext()) {
Entry entry = itr.next();
// get key
K key = entry.getKey();
// get value
V value = entry.getValue();
}
2、通過Key來對Map排序
排序需要對Map的ke進行頻繁的操作,一種方式就是通過比較器(comparator )來實現:
List list = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator() {
@Override
public int compare(Entry e1, Entry e2) {
return e1.getKey().compareTo(e2.getKey());
}
});
另外一種方法就是通過SortedMap,但必須要實現Comparable介面。
SortedMap sortedMap = new TreeMap(new Comparator() {
@Override
public int compare(K k1, K k2) {
return k1.compareTo(k2);
}
});
sortedMap.putAll(map);
3、對value對Map進行排序
這與上一點有些類似,代碼如下:
List list = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator() {
@Override
public int compare(Entry e1, Entry e2) {
return e1.getValue().compareTo(e2.getValue());
}
});
4、初始化一個static 的常量Map
當你希望創建一個全局靜態Map的時候,我們有以下兩種方式,而且是線程安全的。
而在Test1中,我們雖然聲明了map是靜態的,但是在初始化時,我們依然可以改變它的值,就像Test1.map.put(3,」three」);
在Test2中,我們通過一個內部類,將其設置為不可修改,那麼當我們運行Test2.map.put(3,」three」)的時候,它就會拋出一個UnsupportedOperationException 異常來禁止你修改。
public class Test1 {
private static final Map map;
static {
map = new HashMap();
map.put(1, 「one」);
map.put(2, 「two」);
}
}
public class Test2 {
private static final Map map;
static {
Map aMap = new HashMap();
aMap.put(1, 「one」);
aMap.put(2, 「two」);
map = Collections.unmodifiableMap(aMap);
}
}
5、HashMap, TreeMap, and Hashtable之間的不同
在Map介面中,共有三種實現:HashMap,TreeMap,Hashtable。
它們之間各有不同,詳細內容請參考《 HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap》一文。
6、Map中的反向查詢
我們在Map添加一個鍵值對後,意味著這在Map中鍵和值是一一對應的,一個鍵就是對應一個值。但是有時候我們需要反向查詢,比如通過某一個值來查找它的鍵,這種數據結構被稱為bidirectional map,遺憾的是JDK並沒有對其支持。
Apache和Guava 共同提供了這種bidirectional map實現,它在實現中它規定了鍵和值都是必須是1:1的關系。
7、對Map的復制
java中提供了很多方法都可以實現對一個Map的復制,但是那些方法不見得會時時同步。簡單說,就是一個Map發生的變化,而復制的那個依然保持原樣。下面是一個比較高效的實現方法:
Map copiedMap = Collections.synchronizedMap(map);
當然還有另外一個方法,那就是克隆。但是我們的java鼻祖Josh
Bloch卻不推薦這種方式,他曾經在一次訪談中說過關於Map克隆的問題:在很多類中都提供了克隆的方法,因為人們確實需要。但是克隆非常有局限性,而
且在很多時候造成了不必要的影響。(原文《Copy constructor versus cloning》)
8、創建一個空的Map
如果這個map被置為不可用,可以通過以下實現
map = Collections.emptyMap();
相反,我們會用到的時候,就可以直接
map = new HashMap();