为什么php使用文件作为数据缓存,而JAVA使用Static Map?

JAVA和PHP区别

1.synchronized线程同步

在java 是支持多线程的,所以可以使用同步代码块或者同步关键词来约束 ,达到多线程同步执行的目的。
而在 php中只是单线程,虽然支持了Tread关键词,也需要使用 Thread Safe的PHP,而apache服务器可以多线程并发,所以对于php中多线程的控制就变成一个重要的问题?
如何达到线程同步? 最有效的方式 就是文件的锁机制,也就是独占锁和共享锁2种, 一种对应读所用的锁 ,一种是写所用的锁 ,当该方法被锁住的时候,其他线程的到来,就会出现一个排队的现象,也就是同步执行。

2.static关键词

在java中 static关键词约束的变量 会随着java虚拟机启动来开辟内存,等到java虚拟机运行结束后,内存被释放掉。
也就是说:当您多次请求一个servlet,static变量做+1操作,随着访问次数的增加,变量值也是越来越大的。

在php中 static 关键词约束的变量,当请求单个php文件时候开辟内存,等到单个php执行结束后,释放内存。
也是就是说:当您多次请求一个php文件,static变量做+1操作,随着访问次数的增加,变量值始终是1。

在java中可以用static 的map作为缓存容器,因为它可以缓存数据,多次请求变量的值也不会丢。
在php中不可以用static约束的数组最为缓存容器,是因为它缓存不到数据,一次请求后的数据就丢了。

如何来解决这个问题?  
1.使用$globals为超全局变量,当请求php文件的时候,读取php配置到$globals,所以每次请求缓存的数据也是会丢失的。(不可行)
2.写入内存,php提供了可以直接操作内存的方法,php中直接操作内存,要非常小心,新手切记。
3.写入文件,把数据写入到文件中,写入文件配合达到线程同步的文件锁,这是比较好的搭配。

php要求把写入文件的内容只能为字符串,所以如果要把一个数组写入到一个文件里,您这里需要把数组转为字符串,1.print_r(数组);这样虽然写进去了但是同时也打印到页面上了,2.使用serialize(数组) ,使用序列化数组和反序列化字符串来实现转化。个人认为这个比较好。


php自定义缓存对象实现类

<?php
/**
 * @author qiyulin
 * 自定义缓存
 * **/
class Cache {
//缓存
private static $cache_time=864000;//缓存时长 默认值1天
//得到缓存
public  static  function getCache($key){
$cache =Cache::getCachePath($key);
$fp = fopen($cache , 'r'); 
flock($fp, LOCK_EX) or die("lock error");//添加独占锁
//方法
$arr;
if(file_exists($cache)){
//存在
$content =unserialize(fread($fp,filesize($cache)));
if(!empty($content)){
$arr=$content;
}else{
$arr="";
}
}else{
$arr="";
}
//方法结束
flock($fp, LOCK_UN);   
fclose($fp);
return $arr;  
}
//写入缓存
public static function putCache($key,$value){
$cache =Cache::getCachePath($key);
$fp = fopen($cache , 'w'); 
flock($fp, LOCK_EX) or die("lock error");//添加独占锁
//这个地方还要检是否有$key的缓存  有的话清除原来的缓存、
$current = strtotime("now");
$lifetime= empty($value["cache_time"])?Cache::$cache_time:$value["cache_time"];
$value["__last_time"]= $lifetime+$current;//结束时间
fwrite($fp,serialize($value));
//方法结束
flock($fp, LOCK_UN);   
fclose($fp);
}
//踢掉一个缓存数据
public static  function clearCache($key){
$cache =Cache::getCachePath($key);
$fp = fopen($cache , 'w'); 
flock($fp, LOCK_EX) or die("lock error");//添加独占锁
//方法
if(file_exists($fp)){
//存在
fwrite($fp,"");//重写内容为空
}
//结束
flock($fp, LOCK_UN);   
fclose($fp);
}
//实现判断是否过期---过期 true 不过期false
public static function cacheExpired($key){
//1.检查缓存中是否存在 该key  没有表示已经过期
//2.如果 有 key 则检查 lifetime是否过期
$cache =Cache::getCachePath($key);
$cm =unserialize(file_get_contents($cache));
if(!empty($cm)){
$endtime=$cm["__last_time"];//缓存过期时间
$current = strtotime("now");
$lifetime=empty($cm["cache_time"])?Cache::$cache_time:$cm["cache_time"];
echo $endtime."-----".$current."------x---".$lifetime;
if($endtime-$current<$lifetime&&$endtime-$current>0){ //只要时间间隔 在 0~lifetime之间  表示缓存有效
return false;//缓存未过期
}else{
file_put_contents($cache, "");//清空缓存
return true;
}
}
return true;
}

//获取缓存文件在什么地方
public static function getCachePath($key){
$file = dirname(dirname(dirname(__FILE__)));//上层目录
$filename=$file.DIRECTORY_SEPARATOR."cache".DIRECTORY_SEPARATOR.$key.".cache";
return $filename;
}
}
?>



猜你喜欢

转载自blog.csdn.net/qilin001cs/article/details/79108286