idleConnectionTestPerio:当数据库重启后或者由于某种原因进程被杀掉后,C3P0 不会自动重新初始化数据库连接池,当新的请求需要访问数据库的时候,此时会报错误 (因为连接失效),同时刷新数据库连接池,丢弃掉已经失效的连接,当第二个请求到来时恢复正常。C3P0 目前没有提供当获取已建立连接失败后重试次数的参数,只有获取新连接失败后重试次数的参数。
acquireRetryAttempts:该参数的作用是设置系统自动检查连接池中连接是否正常的一个频率参数,时间单位是秒。
acquireIncremen:当连接池中的的连接耗尽的时候 c3p0 一次同时获取的连接数,也就是说,如果使用的连接数已经达到了 maxPoolSize,c3p0 会立即建立新的连接。
maxIdleTim:另外,C3P0 默认不会 close 掉不用的连接池,而是将其回收到可用连接池中,这样会导致连接数越来越大,所以需要设置 maxIdleTime(默认 0,表示永远不过期),单位是秒,maxIdleTime 表示 idle 状态的 connection 能存活的最大时间。
如果使用 spring,同时项目中不使用 JNDI,又不想配置 Hibernate,可以直接将 C3P0 配置到 dataSource 中即可,如清单 9 所示。
清单 9.Spring 配置 <bean destroy-method="close"> <property><value>oracle.jdbc.driver.OracleDriver</value></property> <property><value>jdbc:oracle:thin:@localhost:1521:Test</value></property> <property><value>Kay</value></property> <property><value>root</value></property> <!--连接池中保留的最小连接数。--> <property value="10" /> <!--连接池中保留的最大连接数。Default: 15 --> <property value="100" /> <!--最大空闲时间,1800 秒内未使用则连接被丢弃。若为 0 则永不丢弃。Default: 0 --> <property value="1800" /> <!--当连接池中的连接耗尽的时候 c3p0 一次同时获取的连接数。Default: 3 --> <property value="3" /> <property value="1000" /> <property value="10" /> <!--每 60 秒检查所有连接池中的空闲连接。Default: 0 --> <property value="60" /> <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 --> <property value="30" /> <property value="true" /> <property value="false" /> </bean>类似的做法存在很多种,用户可以自行上网搜索。
计算方式转换计算方式转换比较出名的是时间换空间方式,它通常用于嵌入式设备,或者内存、硬盘空间不足的情况。通过使用牺牲 CPU 的方式,获得原本需要更多内存或者硬盘空间才能完成的工作。
一个非常简单的时间换空间的算法,实现了 a、b 两个变量的值交换。交换两个变量最常用的方法是使用一个中间变量,而引入额外的变量意味着要使用更多的空间。采用下面的方法可以免去中间变量,而达到变量交换的目的,其代价是引入了更多的 CPU 运算。
清单 10. 示例代码 a=a+b; b=a-b; a=a-b;另一个较为有用的例子是对无符号整数的支持。在 Java 语言中,不支持无符号整数,这意味着当需要无符号的 Byte 时,需要使用 Short 代替,这也意味着空间的浪费。下面代码演示了使用位运算模拟无符号 Byte。虽然在取值和设值过程中需要更多的 CPU 运算,但是可以大大降低对内存空间的需求。
清单 11. 无符号整数运算 public class UnsignedByte { public short getValue(byte i){//将 byte 转为无符号的数字 short li = (short)(i & 0xff); return li; } public byte toUnsignedByte(short i){ return (byte)(i & 0xff);//将 short 转为无符号 byte } public static void main(String[] args){ UnsignedByte ins = new UnsignedByte(); short[] shorts = new short[256];//声明一个 short 数组 for(int i=0;i<shorts.length;i++){//数组不能超过无符号 byte 的上限 shorts[i]=(short)i; } byte[] bytes = new byte[256];//使用 byte 数组替代 short 数组 for(int i=0;i<bytes.length;i++){ bytes[i]=ins.toUnsignedByte(shorts[i]);//short 数组的数据存到 byte 数组中 } for(int i=0;i<bytes.length;i++){ System.out.println(ins.getValue(bytes[i])+" ");//从 byte 数组中取出无符号的 byte } } }运行输出如清单 12 所示,篇幅所限,只显示到 10 为止。
清单 12. 运行输出 0 1 2 3 4 5 6 7 8 9 10如果 CPU 的能力较弱,可以采用牺牲空间的方式提高计算能力,实例代码如清单 13 所示。
清单 13. 提高计算能力 import java.util.Arrays; import java.util.HashMap; import java.util.Map; public class SpaceSort { public static int arrayLen = 1000000; public static void main(String[] args){ int[] a = new int[arrayLen]; int[] old = new int[arrayLen]; Map<Integer,Object> map = new HashMap<Integer,Object>(); int count = 0; while(count < a.length){ //初始化数组 int value = (int)(Math.random()*arrayLen*10)+1; if(map.get(value)==null){ map.put(value, value); a[count] = value; count++; } } System.arraycopy(a, 0, old, 0, a.length);//从 a 数组拷贝所有数据到 old 数组 long start = System.currentTimeMillis(); Arrays.sort(a); System.out.println("Arrays.sort spend:"+(System.currentTimeMillis() - start)+"ms"); System.arraycopy(old, 0, a, 0, old.length);//恢复 原有数据 start = System.currentTimeMillis(); spaceTotime(a); System.out.println("spaceTotime spend:"+(System.currentTimeMillis() - start)+"ms"); } public static void spaceTotime(int[] array){ int i = 0; int max = array[0]; int l = array.length; for(i=1;i<l;i++){ if(array[i]>max){ max = array[i]; } } int[] temp = new int[max+1]; for(i=0;i<l;i++){ temp[array[i]] = array[i]; } int j = 0; int max1 = max + 1; for(i=0;i<max1;i++){ if(temp[i] > 0){ array[j++] = temp[i]; } } } }