<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ……天天向上

    好的想法總是無(wú)窮無(wú)盡

    統(tǒng)計(jì)

    留言簿(1)

    閱讀排行榜

    評(píng)論排行榜

    2012年5月24日 #

    calendar獲取當(dāng)前日期及時(shí)間的用例

    1. import Java.util.*;
    2.   public class ShowDate {
    3.   public static void main(String[] args) {
    4.   Calendar calendar = new GregorianCalendar();
    5.   Date trialTime = new Date();
    6.   calendar.setTime(trialTime);
    7.   // print out a bunch of interesting things
    8.   System.out.println("ERA: " + calendar.get(Calendar.ERA));
    9.   System.out.println("YEAR: " + calendar.get(Calendar.YEAR));
    10.   System.out.println("MONTH: " + calendar.get(Calendar.MONTH));
    11.   System.out.println("WEEK_OF_YEAR: " + calendar.get(Calendar.WEEK_OF_YEAR));
    12.   System.out.println("WEEK_OF_MONTH: " + calendar.get(Calendar.WEEK_OF_MONTH));
    13.   System.out.println("DATE: " + calendar.get(Calendar.DATE));
    14.   System.out.println("DAY_OF_MONTH: " + calendar.get(Calendar.DAY_OF_MONTH));
    15.   System.out.println("DAY_OF_YEAR: " + calendar.get(Calendar.DAY_OF_YEAR));
    16.   System.out.println("DAY_OF_WEEK: " + calendar.get(Calendar.DAY_OF_WEEK));
    17.   System.out.println("DAY_OF_WEEK_IN_MONTH: " + calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH));
    18.   System.out.println("AM_PM: " + calendar.get(Calendar.AM_PM));
    19.   System.out.println("HOUR: " + calendar.get(Calendar.HOUR));
    20.   System.out.println("HOUR_OF_DAY: " + calendar.get(Calendar.HOUR_OF_DAY));
    21.   System.out.println("MINUTE: " + calendar.get(Calendar.MINUTE));
    22.   System.out.println("SECOND: " + calendar.get(Calendar.SECOND));
    23.   System.out.println("MILLISECOND: " + calendar.get(Calendar.MILLISECOND));
    24.   System.out.println("ZONE_OFFSET: " + (calendar.get(Calendar.ZONE_OFFSET)/(60*60*1000)));
    25.   System.out.println("DST_OFFSET: " + (calendar.get(Calendar.DST_OFFSET)/(60*60*1000)));
    26.   System.out.println("Current Time, with hour reset to 3");
    27.   calendar.clear(Calendar.HOUR_OF_DAY); // so doesn't override
    28.   calendar.set(Calendar.HOUR, 3);
    29.   System.out.println("ERA: " + calendar.get(Calendar.ERA));
    30.   System.out.println("YEAR: " + calendar.get(Calendar.YEAR));
    31.   System.out.println("MONTH: " + calendar.get(Calendar.MONTH));
    32.   System.out.println("WEEK_OF_YEAR: " + calendar.get(Calendar.WEEK_OF_YEAR));
    33.   System.out.println("WEEK_OF_MONTH: " + calendar.get(Calendar.WEEK_OF_MONTH));
    34.   System.out.println("DATE: " + calendar.get(Calendar.DATE));
    35.   System.out.println("DAY_OF_MONTH: " + calendar.get(Calendar.DAY_OF_MONTH));
    36.   System.out.println("DAY_OF_YEAR: " + calendar.get(Calendar.DAY_OF_YEAR));
    37.   System.out.println("DAY_OF_WEEK: " + calendar.get(Calendar.DAY_OF_WEEK));
    38.   System.out.println("DAY_OF_WEEK_IN_MONTH: " + calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH));

    posted @ 2012-09-19 09:51 japper 閱讀(6351) | 評(píng)論 (0)編輯 收藏

    Android SDK下載和更新失敗的解決方法


    Android SDK下載和更新失敗的解決方法

     

    最近剛換了電腦,開(kāi)始搭建Android開(kāi)發(fā)環(huán)境的時(shí)候,下載SDK總是會(huì)出現(xiàn)如下錯(cuò)誤:
     
    1.Failed to fetch URL http://dl-ssl.google.com/Android/repository/addons_list-1.xml
    據(jù)說(shuō)dl-ssl.google.com在大陸被強(qiáng)了,偉大的天朝真是不讓人活了,解決方法就是修改C:\Windows\System32\drivers\etc\hosts文件。添加一行:
     
    1.74.125.237.1       dl-ssl.google.com 
    這里需要注意的是hosts文件是只讀的,我們沒(méi)有權(quán)限修改,需要我們將hosts文件復(fù)制到桌面或者其他地方,然后修改,代碼如下:
    1.# Copyright (c) 1993-2009 Microsoft Corp. 
    2.# 
    3.# This is a sample HOSTS file used by Microsoft TCP/IP for Windows. 
    4.# 
    5.# This file contains the mappings of IP addresses to host names. Each 
    6.# entry should be kept on an individual line. The IP address should 
    7.# be placed in the first column followed by the corresponding host name. 
    8.# The IP address and the host name should be separated by at least one 
    9.# space. 
    10.# 
    11.# Additionally, comments (such as these) may be inserted on individual 
    12.# lines or following the machine name denoted by a '#' symbol. 
    13.# 
    14.# For example: 
    15.# 
    16.#      102.54.94.97     rhino.acme.com          # source server 
    17.#       38.25.63.10     x.acme.com              # x client host 
    18. 
    19.# localhost name resolution is handled within DNS itself. 
    20.#   127.0.0.1       localhost 
    21.#   ::1             localhost 
    22.//親,就是增加這一句哦  
    23.74.125.237.1       dl-ssl.google.com 
    然后保存,復(fù)制修改后的hosts文件到C:\Windows\System32\drivers\etc 目錄,替換文件就好!!!我們?cè)俅蜗螺dSDK的時(shí)候就會(huì)成功啦,如下圖:
     


    嘿嘿,大功告成啦!!!
     
    PS:補(bǔ)充下,在mac或Linux中,hosts文件所在位置為/etc/hosts,可以使用sudo vim /etc/hosts來(lái)編輯。

    posted @ 2012-09-10 11:18 japper 閱讀(347) | 評(píng)論 (0)編輯 收藏

    免安裝版Tomcat 6.0.35碰到的問(wèn)題 :打開(kāi)tomcat管理界面時(shí),用戶名和密碼錯(cuò)誤的設(shè)置方法

    Tomcat 6.0.35 的功能有些不同于Tomcat 6.0.20。我下載的Tomcat 6.0.35是免安裝的,而以前使用的Tomcat 6.0.20是需要安裝的,而且Tomcat 6.0.20 的安裝密碼,即進(jìn)入Tomcat Manager 這個(gè)地方的密碼是在安裝的時(shí)候指定的,但是呢,Tomcat 6.0.35 由于是免安裝的,所以就沒(méi)有地方去指定密碼了,當(dāng)我們?cè)L問(wèn)Tomcat 6.0.35 的Tomcat Manager的時(shí)候 ,輸入以前默認(rèn)的用戶名:admin 密碼為空,會(huì)發(fā)現(xiàn)出現(xiàn)了403 錯(cuò)誤,即access deny 。調(diào)試了好久,最后終于找出原因了。根據(jù)403頁(yè)面的提示,需要在tomcat的配置文件中(即conf/tomcat-users.xml)加入

    <role rolename="manager-gui"/>

    <user username="admin" password="" roles="manager-gui"/>

    有一點(diǎn)必須注意,其中的rolename 必須是“manager-gui” ,更改成admin 或者 admin-gui,都不好用,而下面的username  password是可以任意的,但是后面的roles 必須和上面role 中的rolename相同。

    posted @ 2012-09-05 14:22 japper 閱讀(3833) | 評(píng)論 (0)編輯 收藏

    通過(guò) jconsole查看tomcat運(yùn)行情況的配置方法

    通過(guò) jconsole查看tomcat運(yùn)行情況的配置方法

    ——基于JDK1.5LinuxRedhat5.5)、Tomcat6

    由于項(xiàng)目的原因,需要使用jconsole對(duì)tomcat進(jìn)行遠(yuǎn)程監(jiān)控,結(jié)合網(wǎng)上的資料對(duì)配置方法進(jìn)行了總結(jié)。

    第一步、配置tomcat

    打開(kāi)%TOMCAT_HOME%/bin下的文件catalina.sh搜索“JAVA_OPTS”找到下面這行:

    if [ -z "$LOGGING_MANAGER" ]; then

      JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"

    else

      JAVA_OPTS="$JAVA_OPTS $LOGGING_MANAGER"

    fi 

    在每個(gè)“JAVA_OPTS”后邊都添加以下標(biāo)黃代碼段,且在一行顯示

    if [ -z "$LOGGING_MANAGER" ]; then

      JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.rmi.server.hostname=192.9.100.48  -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port="9004" -Dcom.sun.management.jmxremote.authenticate="false" -Dcom.sun.management.jmxremote.ssl="false""

    else 

      JAVA_OPTS="$JAVA_OPTS $LOGGING_MANAGER -Djava.rmi.server.hostname=192.9.100.48  -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port="9004" -Dcom.sun.management.jmxremote.authenticate="false" -Dcom.sun.management.jmxremote.ssl="false""

    fi

    其中-Djava.rmi.server.hostname項(xiàng)必須設(shè)置,否則遠(yuǎn)程連接會(huì)因?yàn)榻馕龅?/font>127.0.0.1失敗,該項(xiàng)的值就是你在windows客戶端連接linux時(shí)的ip地址

    -Dcom.sun.management.jmxremote.port="9004"項(xiàng)設(shè)置遠(yuǎn)程連接端口,不要與其他應(yīng)用沖突

    sslauthenticate設(shè)置為false,如果需要安全,請(qǐng)不要false

    、重啟tomcat

    使用root身份登錄系統(tǒng),進(jìn)入%TOMCAT_HOME%/bin目錄下:

    [root@test ~]#ps ef |grep tomcat -輸入命令查看是否存在tomcat進(jìn)程

    [root@test ~]#./shutdown.sh--停止tomcat服務(wù),如果無(wú)效使用kill命令殺掉進(jìn)程

    [root@test ~]#./startup.sh  --啟動(dòng)tomcat服務(wù)

    、運(yùn)行jconsole

    進(jìn)入JDK安裝目錄%JDK_HOME%/bin下,找到“jconsole.exe”,點(diǎn)擊運(yùn)行并選擇【遠(yuǎn)程】選項(xiàng)卡:

    在【主機(jī)名或ip】輸入要遠(yuǎn)程監(jiān)控的tomcat服務(wù)器地址

    在【端口】輸入上文設(shè)置的端口號(hào):9004

    【用戶名、口令】為空,點(diǎn)擊【連接】進(jìn)入監(jiān)控界面。

    posted @ 2012-09-05 14:16 japper 閱讀(3957) | 評(píng)論 (0)編輯 收藏

    TOMCAT獲取信息:JMXServiceURL 、JMXConnector 和MBeanServerConnection

    1. import java.lang.management.MemoryUsage;
    2. import java.text.SimpleDateFormat;
    3. import java.util.Date;
    4. import java.util.Formatter;
    5. import java.util.HashMap;
    6. import java.util.Iterator;
    7. import java.util.Map;
    8. import java.util.Set;
    9. import javax.management.MBeanAttributeInfo;
    10. import javax.management.MBeanInfo;
    11. import javax.management.MBeanServerConnection;
    12. import javax.management.ObjectInstance;
    13. import javax.management.ObjectName;
    14. import javax.management.openmbean.CompositeDataSupport;
    15. import javax.management.remote.JMXConnector;
    16. import javax.management.remote.JMXConnectorFactory;
    17. import javax.management.remote.JMXServiceURL;
    18. public class test {
    19. /**
    20. * @param args
    21. */
    22. public static void main(String[] args) {
    23. try {
    24. String jmxURL = "service:jmx:rmi:///jndi/rmi://192.168.1.126:10090/jmxrmi";//tomcat jmx url
    25. JMXServiceURL serviceURL = new JMXServiceURL(jmxURL);
    26. Map map = new HashMap();
    27. String[] credentials = new String[] { "monitorRole", "QED" };
    28. map.put("jmx.remote.credentials", credentials);
    29. JMXConnector connector = JMXConnectorFactory.connect(serviceURL, map);
    30. MBeanServerConnection mbsc = connector.getMBeanServerConnection();
    31. //端口最好是動(dòng)態(tài)取得
    32. ObjectName threadObjName = new ObjectName("Catalina:type=ThreadPool,name=http-8089");
    33. MBeanInfo mbInfo = mbsc.getMBeanInfo(threadObjName);
    34. String attrName = "currentThreadCount";//tomcat的線程數(shù)對(duì)應(yīng)的屬性值
    35. MBeanAttributeInfo[] mbAttributes = mbInfo.getAttributes();
    36. System.out.println("currentThreadCount:" + mbsc.getAttribute(threadObjName, attrName));
    37. //heap
    38. for (int j = 0; j < mbsc.getDomains().length; j++) {
    39. System.out.println("###########" + mbsc.getDomains()[j]);
    40. }
    41. Set MBeanset = mbsc.queryMBeans(null, null);
    42. System.out.println("MBeanset.size() : " + MBeanset.size());
    43. Iterator MBeansetIterator = MBeanset.iterator();
    44. while (MBeansetIterator.hasNext()) {
    45. ObjectInstance objectInstance = (ObjectInstance) MBeansetIterator.next();
    46. ObjectName objectName = objectInstance.getObjectName();
    47. String canonicalName = objectName.getCanonicalName();
    48. System.out.println("canonicalName : " + canonicalName);
    49. if (canonicalName.equals("Catalina:host=localhost,type=Cluster")) {
    50. // Get details of cluster MBeans
    51. System.out.println("Cluster MBeans Details:");
    52. System.out.println("=========================================");
    53. //getMBeansDetails(canonicalName);
    54. String canonicalKeyPropList = objectName.getCanonicalKeyPropertyListString();
    55. }
    56. }
    57. //------------------------- system ----------------------
    58. ObjectName runtimeObjName = new ObjectName("java.lang:type=Runtime");
    59. System.out.println("廠商:" + (String) mbsc.getAttribute(runtimeObjName, "VmVendor"));
    60. System.out.println("程序:" + (String) mbsc.getAttribute(runtimeObjName, "VmName"));
    61. System.out.println("版本:" + (String) mbsc.getAttribute(runtimeObjName, "VmVersion"));
    62. Date starttime = new Date((Long) mbsc.getAttribute(runtimeObjName, "StartTime"));
    63. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    64. System.out.println("啟動(dòng)時(shí)間:" + df.format(starttime));
    65. Long timespan = (Long) mbsc.getAttribute(runtimeObjName, "Uptime");
    66. System.out.println("連續(xù)工作時(shí)間:" + test.formatTimeSpan(timespan));
    67. //------------------------ JVM -------------------------
    68. //堆使用率
    69. ObjectName heapObjName = new ObjectName("java.lang:type=Memory");
    70. MemoryUsage heapMemoryUsage = MemoryUsage.from((CompositeDataSupport) mbsc.getAttribute(heapObjName,
    71. "HeapMemoryUsage"));
    72. long maxMemory = heapMemoryUsage.getMax();//堆最大
    73. long commitMemory = heapMemoryUsage.getCommitted();//堆當(dāng)前分配
    74. long usedMemory = heapMemoryUsage.getUsed();
    75. System.out.println("heap:" + (double) usedMemory * 100 / commitMemory + "%");//堆使用率
    76. MemoryUsage nonheapMemoryUsage = MemoryUsage.from((CompositeDataSupport) mbsc.getAttribute(heapObjName,
    77. "NonHeapMemoryUsage"));
    78. long noncommitMemory = nonheapMemoryUsage.getCommitted();
    79. long nonusedMemory = heapMemoryUsage.getUsed();
    80. System.out.println("nonheap:" + (double) nonusedMemory * 100 / noncommitMemory + "%");
    81. ObjectName permObjName = new ObjectName("java.lang:type=MemoryPool,name=Perm Gen");
    82. MemoryUsage permGenUsage = MemoryUsage.from((CompositeDataSupport) mbsc.getAttribute(permObjName, "Usage"));
    83. long committed = permGenUsage.getCommitted();//持久堆大小
    84. long used = heapMemoryUsage.getUsed();//
    85. System.out.println("perm gen:" + (double) used * 100 / committed + "%");//持久堆使用率
    86. //-------------------- Session ---------------
    87. ObjectName managerObjName = new ObjectName("Catalina:type=Manager,*");
    88. Set<ObjectName> s = mbsc.queryNames(managerObjName, null);
    89. for (ObjectName obj : s) {
    90. System.out.println("應(yīng)用名:" + obj.getKeyProperty("path"));
    91. ObjectName objname = new ObjectName(obj.getCanonicalName());
    92. System.out.println("最大會(huì)話數(shù):" + mbsc.getAttribute(objname, "maxActiveSessions"));
    93. System.out.println("會(huì)話數(shù):" + mbsc.getAttribute(objname, "activeSessions"));
    94. System.out.println("活動(dòng)會(huì)話數(shù):" + mbsc.getAttribute(objname, "sessionCounter"));
    95. }
    96. //----------------- Thread Pool ----------------
    97. ObjectName threadpoolObjName = new ObjectName("Catalina:type=ThreadPool,*");
    98. Set<ObjectName> s2 = mbsc.queryNames(threadpoolObjName, null);
    99. for (ObjectName obj : s2) {
    100. System.out.println("端口名:" + obj.getKeyProperty("name"));
    101. ObjectName objname = new ObjectName(obj.getCanonicalName());
    102. System.out.println("最大線程數(shù):" + mbsc.getAttribute(objname, "maxThreads"));
    103. System.out.println("當(dāng)前線程數(shù):" + mbsc.getAttribute(objname, "currentThreadCount"));
    104. System.out.println("繁忙線程數(shù):" + mbsc.getAttribute(objname, "currentThreadsBusy"));
    105. }
    106. } catch (Exception e) {
    107. e.printStackTrace();
    108. }
    109. }
    110. public static String formatTimeSpan(long span) {
    111. long minseconds = span % 1000;
    112. span = span / 1000;
    113. long seconds = span % 60;
    114. span = span / 60;
    115. long mins = span % 60;
    116. span = span / 60;
    117. long hours = span % 24;
    118. span = span / 24;
    119. long days = span;
    120. return (new Formatter()).format("%1$d天 %2$02d:%3$02d:%4$02d.%5$03d", days, hours, mins, seconds, minseconds)
    121. .toString();
    122. }
    123. }

    1. import java.util.Iterator;
    2. import java.util.Set;
    3. import javax.management.Attribute;
    4. import javax.management.MBeanInfo;
    5. import javax.management.MBeanServerConnection;
    6. import javax.management.MBeanServerInvocationHandler;
    7. import javax.management.ObjectInstance;
    8. import javax.management.ObjectName;
    9. import javax.management.remote.JMXConnector;
    10. import javax.management.remote.JMXConnectorFactory;
    11. import javax.management.remote.JMXServiceURL;
    12. public class Client {
    13. public static void main(String[] args) throws Exception {
    14. JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/server");
    15. JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
    16. MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
    17. ObjectName mbeanName = new ObjectName("chengang:name=HelloWorld");
    18. // 把所有Domain都打印出來(lái)
    19. System.out.println("Domains:---------------");
    20. String domains[] = mbsc.getDomains();
    21. for (int i = 0; i < domains.length; i++) {
    22. System.out.println("\tDomain[" + i + "] = " + domains[i]);
    23. }
    24. // MBean的總數(shù)
    25. System.out.println("MBean count = " + mbsc.getMBeanCount());
    26. // 對(duì)name屬性的操作(屬性名的第一個(gè)字母要大寫(xiě))
    27. mbsc.setAttribute(mbeanName, new Attribute("Name", "PANDA"));// 設(shè)值
    28. System.out.println("Name = " + mbsc.getAttribute(mbeanName, "Name"));// 取值
    29. // 得到proxy代理后直接調(diào)用的方式
    30. HelloMBean proxy = (HelloMBean) MBeanServerInvocationHandler.newProxyInstance(mbsc, mbeanName, HelloMBean.class, false);
    31. proxy.printHello();
    32. proxy.printHello("Raymend");
    33. // 遠(yuǎn)程調(diào)用的方式
    34. mbsc.invoke(mbeanName, "printHello", null, null);
    35. mbsc.invoke(mbeanName, "printHello", new Object[] { "熊貓燒香" }, new String[] { String.class.getName() });
    36. // 得mbean的信息
    37. MBeanInfo info = mbsc.getMBeanInfo(mbeanName);
    38. System.out.println("Hello Class: " + info.getClassName());
    39. System.out.println("Hello Attriber:" + info.getAttributes()[0].getName());
    40. System.out.println("Hello Operation:" + info.getOperations()[0].getName());
    41. // 得到所有的MBean的ObjectName
    42. System.out.println("all ObjectName:---------------");
    43. Set set = mbsc.queryMBeans(null, null);
    44. for (Iterator it = set.iterator(); it.hasNext();) {
    45. ObjectInstance oi = (ObjectInstance) it.next();
    46. System.out.println("\t" + oi.getObjectName());
    47. }
    48. // 關(guān)閉MBeanServer連接
    49. jmxc.close();
    50. }
    51. }

    posted @ 2012-09-05 14:14 japper 閱讀(4991) | 評(píng)論 (0)編輯 收藏

    LinkedHashMap和HashMap的比較使用

    由于現(xiàn)在項(xiàng)目中用到了LinkedHashMap,并不是太熟悉就到網(wǎng)上搜了一下。







    import
    java.util.HashMap;

    import
    java.util.Iterator;

    import
    java.util.LinkedHashMap;

    import
    java.util.Map;

    public
    class TestLinkedHashMap {


      public static
    void main(String
    args[])

      {

       System.out.println("*************************LinkedHashMap*************");

       Map<Integer,String> map = new LinkedHashMap<Integer,String>();

       map.put(6, "apple");

       map.put(3, "banana");

       map.put(2,"pear");

      

       for (Iterator it =  map.keySet().iterator();it.hasNext();)

       {

        Object key = it.next();

        System.out.println(
    key+
    "="+
    map.get(key));

       }

      

       System.out.println("*************************HashMap*************");

       Map<Integer,String>
    map1 =
    new  HashMap<Integer,String>();

       map1.put(6, "apple");

       map1.put(3, "banana");

       map1.put(2,"pear");

      

       for (Iterator it = map1.keySet().iterator();it.hasNext();)

       {

        Object key = it.next();

        System.out.println(
    key+
    "="+
    map1.get(key));

       }

      }

    }


    運(yùn)行結(jié)果如下:


    *************************LinkedHashMap*************
    6=apple
    3=banana
    2=pear
    *************************HashMap**************************
    2=pear
    6=apple
    3=banana


    分析:LinkedHashmap 的特點(diǎn)是put進(jìn)去的對(duì)象位置未發(fā)生變化,而HashMap會(huì)發(fā)生變化.


    再普及下:




    java為數(shù)據(jù)結(jié)構(gòu)中的映射定義了一個(gè)接口java.util.Map;它有四個(gè)實(shí)現(xiàn)類(lèi),分別是HashMap
    Hashtable LinkedHashMap 和TreeMap
    .


    Map主要用于存儲(chǔ)健值對(duì),根據(jù)鍵得到值,因此不允許鍵重復(fù)(重復(fù)了覆蓋了),但允許值重復(fù)。
    Hashmap
    是一個(gè)最常用的Map,它根據(jù)鍵的HashCode值存儲(chǔ)數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問(wèn)速度,遍歷時(shí),取得數(shù)據(jù)的順序是完全隨機(jī)的。
    HashMap最多只允許一條記錄的鍵為Null;允許多條記錄的值為
    Null;HashMap不支持線程的同步,即任一時(shí)刻可以有多個(gè)線程同時(shí)寫(xiě)HashMap;可能會(huì)導(dǎo)致數(shù)據(jù)的不一致。如果需要同步,可以用
    Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。


    Hashtable與
    HashMap類(lèi)似,它繼承自Dictionary類(lèi),不同的是:它不允許記錄的鍵或者值為空;它支持線程的同步,即任一時(shí)刻只有一個(gè)線程能寫(xiě)Hashtable,因此也導(dǎo)致了
    Hashtable在寫(xiě)入時(shí)會(huì)比較慢。


    LinkedHashMap
    是HashMap的一個(gè)子類(lèi),保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時(shí),先得到的記錄肯定是先插入的.也可以在構(gòu)造時(shí)用帶參數(shù),按照應(yīng)用次數(shù)排序。在遍歷的時(shí)候會(huì)比HashMap慢,不過(guò)有種情況例外,當(dāng)HashMap容量很大,實(shí)際數(shù)據(jù)較少時(shí),遍歷起來(lái)可能會(huì)比
    LinkedHashMap慢,因?yàn)長(zhǎng)inkedHashMap的遍歷速度只和實(shí)際數(shù)據(jù)有關(guān),和容量無(wú)關(guān),而HashMap的遍歷速度和他的容量有關(guān)。


    TreeMap實(shí)現(xiàn)SortMap接口,能夠把它保存的記錄根據(jù)鍵排序,默認(rèn)是按鍵值的升序排序,也可以指定排序的比較器,當(dāng)用Iterator
    遍歷TreeMap時(shí),得到的記錄是排過(guò)序的。


    一般情況下,我們用的最多的是HashMap,在Map 中插入、刪除和定位元素,HashMap
    是最好的選擇。但如果您要按自然順序或自定義順序遍歷鍵,那么TreeMap會(huì)更好。如果需要輸出的順序和輸入的相同,那么用LinkedHashMap
    可以實(shí)現(xiàn),它還可以按讀取順序來(lái)排列.


    HashMap是一個(gè)最常用的Map,它根據(jù)鍵的hashCode值存儲(chǔ)數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問(wèn)速度。HashMap最多只允許一條記錄的鍵為NULL,允許多條記錄的值為NULL。


    HashMap不支持線程同步,即任一時(shí)刻可以有多個(gè)線程同時(shí)寫(xiě)HashMap,可能會(huì)導(dǎo)致數(shù)據(jù)的不一致性。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力。


    Hashtable與HashMap類(lèi)似,不同的是:它不允許記錄的鍵或者值為空;它支持線程的同步,即任一時(shí)刻只有一個(gè)線程能寫(xiě)Hashtable,因此也導(dǎo)致了Hashtable在寫(xiě)入時(shí)會(huì)比較慢。


    LinkedHashMap保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時(shí),先得到的記錄肯定是先插入的。


    在遍歷的時(shí)候會(huì)比HashMap慢TreeMap能夠把它保存的記錄根據(jù)鍵排序,默認(rèn)是按升序排序,也可以指定排序的比較器。當(dāng)用Iterator遍歷TreeMap時(shí),得到的記錄是排過(guò)序的。

    posted @ 2012-09-05 14:12 japper 閱讀(16468) | 評(píng)論 (5)編輯 收藏

    java synchronized詳解 (轉(zhuǎn))

    記下來(lái),很重要。

    Java語(yǔ)言的關(guān)鍵字,當(dāng)它用來(lái)修飾一個(gè)方法或者一個(gè)代碼塊的時(shí)候,能夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼。

         一、當(dāng)兩個(gè)并發(fā)線程訪問(wèn)同一個(gè)對(duì)象object中的這個(gè)synchronized(this)同步代碼塊時(shí),一個(gè)時(shí)間內(nèi)只能有一個(gè)線程得到執(zhí)行。另一個(gè)線程必須等待當(dāng)前線程執(zhí)行完這個(gè)代碼塊以后才能執(zhí)行該代碼塊。

         二、然而,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),另一個(gè)線程仍然可以訪問(wèn)該object中的非synchronized(this)同步代碼塊。

         三、尤其關(guān)鍵的是,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),其他線程對(duì)object中所有其它synchronized(this)同步代碼塊的訪問(wèn)將被阻塞。

         四、第三個(gè)例子同樣適用其它同步代碼塊。也就是說(shuō),當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),它就獲得了這個(gè)object的對(duì)象鎖。結(jié)果,其它線程對(duì)該object對(duì)象所有同步代碼部分的訪問(wèn)都被暫時(shí)阻塞。

         五、以上規(guī)則對(duì)其它對(duì)象鎖同樣適用.

    舉例說(shuō)明: 
         一、當(dāng)兩個(gè)并發(fā)線程訪問(wèn)同一個(gè)對(duì)象object中的這個(gè)synchronized(this)同步代碼塊時(shí),一個(gè)時(shí)間內(nèi)只能有一個(gè)線程得到執(zhí)行。另一個(gè)線程必須等待當(dāng)前線程執(zhí)行完這個(gè)代碼塊以后才能執(zhí)行該代碼塊。

    package ths;

    public class Thread1 implements Runnable { 
         public void run() { 
              synchronized(this) { 
                   for (int i = 0; i < 5; i++) { 
                        System.out.println(Thread.currentThread().getName() + " synchronized loop " + i); 
                   } 
              } 
         } 
         public static void main(String[] args) { 
              Thread1 t1 = new Thread1(); 
              Thread ta = new Thread(t1, "A"); 
              Thread tb = new Thread(t1, "B"); 
              ta.start(); 
              tb.start(); 
         }    
    }

    結(jié)果: 
         A synchronized loop 0 
         A synchronized loop 1 
         A synchronized loop 2 
         A synchronized loop 3 
         A synchronized loop 4 
         B synchronized loop 0 
         B synchronized loop 1 
         B synchronized loop 2 
         B synchronized loop 3 
         B synchronized loop 4

         二、然而,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),另一個(gè)線程仍然可以訪問(wèn)該object中的非synchronized(this)同步代碼塊。

    package ths;

    public class Thread2 { 
         public void m4t1() { 
              synchronized(this) { 
                   int i = 5; 
                   while( i-- > 0) { 
                        System.out.println(Thread.currentThread().getName() + " : " + i); 
                        try { 
                             Thread.sleep(500); 
                        } catch (InterruptedException ie) { 
                        } 
                   } 
              } 
         } 
         public void m4t2() { 
              int i = 5; 
              while( i-- > 0) { 
                   System.out.println(Thread.currentThread().getName() + " : " + i); 
                   try { 
                        Thread.sleep(500); 
                   } catch (InterruptedException ie) { 
                   } 
              } 
         } 
         public static void main(String[] args) { 
              final Thread2 myt2 = new Thread2(); 
              Thread t1 = new Thread(  new Runnable() {  public void run() {  myt2.m4t1();  }  }, "t1"  ); 
              Thread t2 = new Thread(  new Runnable() {  public void run() { myt2.m4t2();   }  }, "t2"  ); 
              t1.start(); 
              t2.start(); 
         }    
    }

    結(jié)果: 
         t1 : 4 
         t2 : 4 
         t1 : 3 
         t2 : 3 
         t1 : 2 
         t2 : 2 
         t1 : 1 
         t2 : 1 
         t1 : 0 
         t2 : 0

         三、尤其關(guān)鍵的是,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),其他線程對(duì)object中所有其它synchronized(this)同步代碼塊的訪問(wèn)將被阻塞。

         //修改Thread2.m4t2()方法: 
         public void m4t2() { 
              synchronized(this) { 
                   int i = 5; 
                   while( i-- > 0) { 
                        System.out.println(Thread.currentThread().getName() + " : " + i); 
                        try { 
                             Thread.sleep(500); 
                        } catch (InterruptedException ie) { 
                        } 
                   } 
              }

         }

    結(jié)果:

         t1 : 4 
         t1 : 3 
         t1 : 2 
         t1 : 1 
         t1 : 0 
         t2 : 4 
         t2 : 3 
         t2 : 2 
         t2 : 1 
         t2 : 0

         四、第三個(gè)例子同樣適用其它同步代碼塊。也就是說(shuō),當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),它就獲得了這個(gè)object的對(duì)象鎖。結(jié)果,其它線程對(duì)該object對(duì)象所有同步代碼部分的訪問(wèn)都被暫時(shí)阻塞。

         //修改Thread2.m4t2()方法如下:

         public synchronized void m4t2() { 
              int i = 5; 
              while( i-- > 0) { 
                   System.out.println(Thread.currentThread().getName() + " : " + i); 
                   try { 
                        Thread.sleep(500); 
                   } catch (InterruptedException ie) { 
                   } 
              } 
         }

    結(jié)果: 
         t1 : 4 
         t1 : 3 
         t1 : 2 
         t1 : 1 
         t1 : 0 
         t2 : 4 
         t2 : 3 
         t2 : 2 
         t2 : 1 
         t2 : 0

         五、以上規(guī)則對(duì)其它對(duì)象鎖同樣適用:

    package ths;

    public class Thread3 {   
         class Inner {    
              private void m4t1() {    
                   int i = 5;    
                   while(i-- > 0) {    
                        System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i);    
                        try {    
                             Thread.sleep(500);    
                        } catch(InterruptedException ie) {    
                        }    
                   }    
              }    
              private void m4t2() {    
                   int i = 5;    
                   while(i-- > 0) {    
                        System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);    
                        try {    
                             Thread.sleep(500);    
                        } catch(InterruptedException ie) {    
                        }    
                   }    
              }    
         }    
         private void m4t1(Inner inner) {    
              synchronized(inner) { //使用對(duì)象鎖    
              inner.m4t1();    
         }    
         private void m4t2(Inner inner) {    
              inner.m4t2();    
         }    
         public static void main(String[] args) {    
              final Thread3 myt3 = new Thread3();    
              final Inner inner = myt3.new Inner();    
              Thread t1 = new Thread( new Runnable() {public void run() { myt3.m4t1(inner);} }, "t1");    
         Thread t2 = new Thread( new Runnable() {public void run() { myt3.m4t2(inner);} }, "t2");    
         t1.start();    
         t2.start();    
      }    
    }

    結(jié)果:

    盡管線程t1獲得了對(duì)Inner的對(duì)象鎖,但由于線程t2訪問(wèn)的是同一個(gè)Inner中的非同步部分。所以兩個(gè)線程互不干擾。

         t1 : Inner.m4t1()=4 
         t2 : Inner.m4t2()=4 
         t1 : Inner.m4t1()=3 
         t2 : Inner.m4t2()=3 
         t1 : Inner.m4t1()=2 
         t2 : Inner.m4t2()=2 
         t1 : Inner.m4t1()=1 
         t2 : Inner.m4t2()=1 
         t1 : Inner.m4t1()=0 
         t2 : Inner.m4t2()=0

    現(xiàn)在在Inner.m4t2()前面加上synchronized:

         private synchronized void m4t2() { 
              int i = 5; 
              while(i-- > 0) { 
                   System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i); 
                   try { 
                        Thread.sleep(500); 
                   } catch(InterruptedException ie) { 
                   } 
              } 
         }

    結(jié)果:

    盡管線程t1與t2訪問(wèn)了同一個(gè)Inner對(duì)象中兩個(gè)毫不相關(guān)的部分,但因?yàn)閠1先獲得了對(duì)Inner的對(duì)象鎖,所以t2對(duì)Inner.m4t2()的訪問(wèn)也被阻塞,因?yàn)閙4t2()是Inner中的一個(gè)同步方法。

         t1 : Inner.m4t1()=4 
         t1 : Inner.m4t1()=3 
         t1 : Inner.m4t1()=2 
         t1 : Inner.m4t1()=1 
         t1 : Inner.m4t1()=0 
         t2 : Inner.m4t2()=4 
         t2 : Inner.m4t2()=3 
         t2 : Inner.m4t2()=2 
         t2 : Inner.m4t2()=1 
         t2 : Inner.m4t2()=0

    第二篇:

    synchronized 關(guān)鍵字,它包括兩種用法:synchronized 方法和 synchronized 塊。 
    1. synchronized 方法:通過(guò)在方法聲明中加入 synchronized關(guān)鍵字來(lái)聲明 synchronized 方法。如: 
    public synchronized void accessVal(int newVal); 
    synchronized 方法控制對(duì)類(lèi)成員變量的訪問(wèn):每個(gè)類(lèi)實(shí)例對(duì)應(yīng)一把鎖,每個(gè) synchronized 方法都必須獲得調(diào)用該方法的類(lèi)實(shí)例的鎖方能

    執(zhí)行,否則所屬線程阻塞,方法一旦執(zhí)行,就獨(dú)占該鎖,直到從該方法返回時(shí)才將鎖釋放,此后被阻塞的線程方能獲得該鎖,重新進(jìn)入可執(zhí)行

    狀態(tài)。這種機(jī)制確保了同一時(shí)刻對(duì)于每一個(gè)類(lèi)實(shí)例,其所有聲明為 synchronized 的成員函數(shù)中至多只有一個(gè)處于可執(zhí)行狀態(tài)(因?yàn)橹炼嘀挥?/p>

    一個(gè)能夠獲得該類(lèi)實(shí)例對(duì)應(yīng)的鎖),從而有效避免了類(lèi)成員變量的訪問(wèn)沖突(只要所有可能訪問(wèn)類(lèi)成員變量的方法均被聲明為 synchronized)

    。 
    在 Java 中,不光是類(lèi)實(shí)例,每一個(gè)類(lèi)也對(duì)應(yīng)一把鎖,這樣我們也可將類(lèi)的靜態(tài)成員函數(shù)聲明為 synchronized ,以控制其對(duì)類(lèi)的靜態(tài)成

    員變量的訪問(wèn)。 
    synchronized 方法的缺陷:若將一個(gè)大的方法聲明為synchronized 將會(huì)大大影響效率,典型地,若將線程類(lèi)的方法 run() 聲明為

    synchronized ,由于在線程的整個(gè)生命期內(nèi)它一直在運(yùn)行,因此將導(dǎo)致它對(duì)本類(lèi)任何 synchronized 方法的調(diào)用都永遠(yuǎn)不會(huì)成功。當(dāng)然我們可

    以通過(guò)將訪問(wèn)類(lèi)成員變量的代碼放到專(zhuān)門(mén)的方法中,將其聲明為 synchronized ,并在主方法中調(diào)用來(lái)解決這一問(wèn)題,但是 Java 為我們提供

    了更好的解決辦法,那就是 synchronized 塊。 
    2. synchronized 塊:通過(guò) synchronized關(guān)鍵字來(lái)聲明synchronized 塊。語(yǔ)法如下: 
    synchronized(syncObject) { 
    //允許訪問(wèn)控制的代碼 

    synchronized 塊是這樣一個(gè)代碼塊,其中的代碼必須獲得對(duì)象 syncObject (如前所述,可以是類(lèi)實(shí)例或類(lèi))的鎖方能執(zhí)行,具體機(jī)

    制同前所述。由于可以針對(duì)任意代碼塊,且可任意指定上鎖的對(duì)象,故靈活性較高。 
    對(duì)synchronized(this)的一些理解    
    一、當(dāng)兩個(gè)并發(fā)線程訪問(wèn)同一個(gè)對(duì)象object中的這個(gè)synchronized(this)同步代碼塊時(shí),一個(gè)時(shí)間內(nèi)只能有一個(gè)線程得到執(zhí)行。另一個(gè)線

    程必須等待當(dāng)前線程執(zhí)行完這個(gè)代碼塊以后才能執(zhí)行該代碼塊。 
    二、然而,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),另一個(gè)線程仍然可以訪問(wèn)該object中的非synchronized

    (this)同步代碼塊。 
    三、尤其關(guān)鍵的是,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),其他線程對(duì)object中所有其它synchronized(this)

    同步代碼塊的訪問(wèn)將被阻塞。 
    四、第三個(gè)例子同樣適用其它同步代碼塊。也就是說(shuō),當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),它就獲得了這個(gè)

    object的對(duì)象鎖。結(jié)果,其它線程對(duì)該object對(duì)象所有同步代碼部分的訪問(wèn)都被暫時(shí)阻塞。 
    五、以上規(guī)則對(duì)其它對(duì)象鎖同樣適用

    http://hi.baidu.com/sunshibing/blog/item/5235b9b731d48ff430add14a.html
    java中synchronized用法

    打個(gè)比方:一個(gè)object就像一個(gè)大房子,大門(mén)永遠(yuǎn)打開(kāi)。房子里有 很多房間(也就是方法)。

    這些房間有上鎖的(synchronized方法), 和不上鎖之分(普通方法)。房門(mén)口放著一把鑰匙(key),這把鑰匙可以打開(kāi)所有上鎖的房間。

    另外我把所有想調(diào)用該對(duì)象方法的線程比喻成想進(jìn)入這房子某個(gè) 房間的人。所有的東西就這么多了,下面我們看看這些東西之間如何作用的。

    在此我們先來(lái)明確一下我們的前提條件。該對(duì)象至少有一個(gè)synchronized方法,否則這個(gè)key還有啥意義。當(dāng)然也就不會(huì)有我們的這個(gè)主題了。

    一個(gè)人想進(jìn)入某間上了鎖的房間,他來(lái)到房子門(mén)口,看見(jiàn)鑰匙在那兒(說(shuō)明暫時(shí)還沒(méi)有其他人要使用上鎖的 房間)。于是他走上去拿到了鑰匙

    ,并且按照自己 的計(jì)劃使用那些房間。注意一點(diǎn),他每次使用完一次上鎖的房間后會(huì)馬上把鑰匙還回去。即使他要連續(xù)使用兩間上鎖的房間,

    中間他也要把鑰匙還回去,再取回來(lái)。

    因此,普通情況下鑰匙的使用原則是:“隨用隨借,用完即還。”

    這時(shí)其他人可以不受限制的使用那些不上鎖的房間,一個(gè)人用一間可以,兩個(gè)人用一間也可以,沒(méi)限制。但是如果當(dāng)某個(gè)人想要進(jìn)入上鎖的房

    間,他就要跑到大門(mén)口去看看了。有鑰匙當(dāng)然拿了就走,沒(méi)有的話,就只能等了。

    要是很多人在等這把鑰匙,等鑰匙還回來(lái)以后,誰(shuí)會(huì)優(yōu)先得到鑰匙?Not guaranteed。象前面例子里那個(gè)想連續(xù)使用兩個(gè)上鎖房間的家伙,他

    中間還鑰匙的時(shí)候如果還有其他人在等鑰匙,那么沒(méi)有任何保證這家伙能再次拿到。 (JAVA規(guī)范在很多地方都明確說(shuō)明不保證,象

    Thread.sleep()休息后多久會(huì)返回運(yùn)行,相同優(yōu)先權(quán)的線程那個(gè)首先被執(zhí)行,當(dāng)要訪問(wèn)對(duì)象的鎖被 釋放后處于等待池的多個(gè)線程哪個(gè)會(huì)優(yōu)先得

    到,等等。我想最終的決定權(quán)是在JVM,之所以不保證,就是因?yàn)镴VM在做出上述決定的時(shí)候,絕不是簡(jiǎn)簡(jiǎn)單單根據(jù) 一個(gè)條件來(lái)做出判斷,而是

    根據(jù)很多條。而由于判斷條件太多,如果說(shuō)出來(lái)可能會(huì)影響JAVA的推廣,也可能是因?yàn)橹R(shí)產(chǎn)權(quán)保護(hù)的原因吧。SUN給了個(gè)不保證 就混過(guò)去了

    。無(wú)可厚非。但我相信這些不確定,并非完全不確定。因?yàn)橛?jì)算機(jī)這東西本身就是按指令運(yùn)行的。即使看起來(lái)很隨機(jī)的現(xiàn)象,其實(shí)都是有規(guī)律

    可尋。學(xué)過(guò) 計(jì)算機(jī)的都知道,計(jì)算機(jī)里隨機(jī)數(shù)的學(xué)名是偽隨機(jī)數(shù),是人運(yùn)用一定的方法寫(xiě)出來(lái)的,看上去隨機(jī)罷了。另外,或許是因?yàn)橐肱?/p>

    的確定太費(fèi)事,也沒(méi)多大意義,所 以不確定就不確定了吧。)

    再來(lái)看看同步代碼塊。和同步方法有小小的不同。

    1.從尺寸上講,同步代碼塊比同步方法小。你可以把同步代碼塊看成是沒(méi)上鎖房間里的一塊用帶鎖的屏風(fēng)隔開(kāi)的空間。

    2.同步代碼塊還可以人為的指定獲得某個(gè)其它對(duì)象的key。就像是指定用哪一把鑰匙才能開(kāi)這個(gè)屏風(fēng)的鎖,你可以用本房的鑰匙;你也可以指定

    用另一個(gè)房子的鑰匙才能開(kāi),這樣的話,你要跑到另一棟房子那兒把那個(gè)鑰匙拿來(lái),并用那個(gè)房子的鑰匙來(lái)打開(kāi)這個(gè)房子的帶鎖的屏風(fēng)。

             記住你獲得的那另一棟房子的鑰匙,并不影響其他人進(jìn)入那棟房子沒(méi)有鎖的房間。

             為什么要使用同步代碼塊呢?我想應(yīng)該是這樣的:首先對(duì)程序來(lái)講同步的部分很影響運(yùn)行效率,而一個(gè)方法通常是先創(chuàng)建一些局部變

    量,再對(duì)這些變量做一些 操作,如運(yùn)算,顯示等等;而同步所覆蓋的代碼越多,對(duì)效率的影響就越嚴(yán)重。因此我們通常盡量縮小其影響范圍。

    如何做?同步代碼塊。我們只把一個(gè)方法中該同 步的地方同步,比如運(yùn)算。

             另外,同步代碼塊可以指定鑰匙這一特點(diǎn)有個(gè)額外的好處,是可以在一定時(shí)期內(nèi)霸占某個(gè)對(duì)象的key。還記得前面說(shuō)過(guò)普通情況下鑰

    匙的使用原則嗎。現(xiàn)在不是普通情況了。你所取得的那把鑰匙不是永遠(yuǎn)不還,而是在退出同步代碼塊時(shí)才還。

              還用前面那個(gè)想連續(xù)用兩個(gè)上鎖房間的家伙打比方。怎樣才能在用完一間以后,繼續(xù)使用另一間呢。用同步代碼塊吧。先創(chuàng)建另外

    一個(gè)線程,做一個(gè)同步代碼 塊,把那個(gè)代碼塊的鎖指向這個(gè)房子的鑰匙。然后啟動(dòng)那個(gè)線程。只要你能在進(jìn)入那個(gè)代碼塊時(shí)抓到這房子的鑰匙

    ,你就可以一直保留到退出那個(gè)代碼塊。也就是說(shuō) 你甚至可以對(duì)本房?jī)?nèi)所有上鎖的房間遍歷,甚至再sleep(10*60*1000),而房門(mén)口卻還有

    1000個(gè)線程在等這把鑰匙呢。很過(guò)癮吧。

              在此對(duì)sleep()方法和鑰匙的關(guān)聯(lián)性講一下。一個(gè)線程在拿到key后,且沒(méi)有完成同步的內(nèi)容時(shí),如果被強(qiáng)制sleep()了,那key還一

    直在 它那兒。直到它再次運(yùn)行,做完所有同步內(nèi)容,才會(huì)歸還key。記住,那家伙只是干活干累了,去休息一下,他并沒(méi)干完他要干的事。為

    了避免別人進(jìn)入那個(gè)房間 把里面搞的一團(tuán)糟,即使在睡覺(jué)的時(shí)候他也要把那唯一的鑰匙戴在身上。

              最后,也許有人會(huì)問(wèn),為什么要一把鑰匙通開(kāi),而不是一個(gè)鑰匙一個(gè)門(mén)呢?我想這純粹是因?yàn)閺?fù)雜性問(wèn)題。一個(gè)鑰匙一個(gè)門(mén)當(dāng)然更

    安全,但是會(huì)牽扯好多問(wèn)題。鑰匙 的產(chǎn)生,保管,獲得,歸還等等。其復(fù)雜性有可能隨同步方法的增加呈幾何級(jí)數(shù)增加,嚴(yán)重影響效率。這也

    算是一個(gè)權(quán)衡的問(wèn)題吧。為了增加一點(diǎn)點(diǎn)安全性,導(dǎo)致效 率大大降低,是多么不可取啊。

    synchronized的一個(gè)簡(jiǎn)單例子

    public class TextThread {

    public static void main(String[] args) {   
       TxtThread tt = new TxtThread();    
       new Thread(tt).start();    
       new Thread(tt).start();    
       new Thread(tt).start();    
       new Thread(tt).start();    
    }    
    }

    class TxtThread implements Runnable {   
    int num = 100;    
    String str = new String();

    public void run() {   
       synchronized (str) {    
        while (num > 0) {

         try {   
          Thread.sleep(1);    
         } catch (Exception e) {    
          e.getMessage();    
         }    
         System.out.println(Thread.currentThread().getName()    
           + "this is " + num--);    
        }    
       }    
    }    
    }

    上面的例子中為了制造一個(gè)時(shí)間差,也就是出錯(cuò)的機(jī)會(huì),使用了Thread.sleep(10)

    Java對(duì)多線程的支持與同步機(jī)制深受大家的喜愛(ài),似乎看起來(lái)使用了synchronized關(guān)鍵字就可以輕松地解決多線程共享數(shù)據(jù)同步問(wèn)題。到底如

    何?――還得對(duì)synchronized關(guān)鍵字的作用進(jìn)行深入了解才可定論。

    總的說(shuō)來(lái),synchronized關(guān)鍵字可以作為函數(shù)的修飾符,也可作為函數(shù)內(nèi)的語(yǔ)句,也就是平時(shí)說(shuō)的同步方法和同步語(yǔ)句塊。如果再細(xì)的分類(lèi),

    synchronized可作用于instance變量、object reference(對(duì)象引用)、static函數(shù)和class literals(類(lèi)名稱(chēng)字面常量)身上。

    在進(jìn)一步闡述之前,我們需要明確幾點(diǎn):

    A.無(wú)論synchronized關(guān)鍵字加在方法上還是對(duì)象上,它取得的鎖都是對(duì)象,而不是把一段代碼或函數(shù)當(dāng)作鎖――而且同步方法很可能還會(huì)被其

    他線程的對(duì)象訪問(wèn)。

    B.每個(gè)對(duì)象只有一個(gè)鎖(lock)與之相關(guān)聯(lián)。

    C.實(shí)現(xiàn)同步是要很大的系統(tǒng)開(kāi)銷(xiāo)作為代價(jià)的,甚至可能造成死鎖,所以盡量避免無(wú)謂的同步控制。

    接著來(lái)討論synchronized用到不同地方對(duì)代碼產(chǎn)生的影響:

    假設(shè)P1、P2是同一個(gè)類(lèi)的不同對(duì)象,這個(gè)類(lèi)中定義了以下幾種情況的同步塊或同步方法,P1、P2就都可以調(diào)用它們。

    1. 把synchronized當(dāng)作函數(shù)修飾符時(shí),示例代碼如下:

    Public synchronized void methodAAA()

    {

    //….

    }

    這也就是同步方法,那這時(shí)synchronized鎖定的是哪個(gè)對(duì)象呢?它鎖定的是調(diào)用這個(gè)同步方法對(duì)象。也就是說(shuō),當(dāng)一個(gè)對(duì)象P1在不同的線程中

    執(zhí)行這個(gè)同步方法時(shí),它們之間會(huì)形成互斥,達(dá)到同步的效果。但是這個(gè)對(duì)象所屬的Class所產(chǎn)生的另一對(duì)象P2卻可以任意調(diào)用這個(gè)被加了

    synchronized關(guān)鍵字的方法。

    上邊的示例代碼等同于如下代碼:

    public void methodAAA()

    {

    synchronized (this)      // (1)

    {

           //…..

    }

    }

    (1)處的this指的是什么呢?它指的就是調(diào)用這個(gè)方法的對(duì)象,如P1。可見(jiàn)同步方法實(shí)質(zhì)是將synchronized作用于object reference。――那個(gè)

    拿到了P1對(duì)象鎖的線程,才可以調(diào)用P1的同步方法,而對(duì)P2而言,P1這個(gè)鎖與它毫不相干,程序也可能在這種情形下擺脫同步機(jī)制的控制,造

    成數(shù)據(jù)混亂:(

    2.同步塊,示例代碼如下:

    public void method3(SomeObject so)

    {

        synchronized(so)

        {   
           //…..    
        }

    }

    這時(shí),鎖就是so這個(gè)對(duì)象,誰(shuí)拿到這個(gè)鎖誰(shuí)就可以運(yùn)行它所控制的那段代碼。當(dāng)有一個(gè)明確的對(duì)象作為鎖時(shí),就可以這樣寫(xiě)程序,但當(dāng)沒(méi)有明

    確的對(duì)象作為鎖,只是想讓一段代碼同步時(shí),可以創(chuàng)建一個(gè)特殊的instance變量(它得是一個(gè)對(duì)象)來(lái)充當(dāng)鎖:

    class Foo implements Runnable

    {

            private byte[] lock = new byte[0]; // 特殊的instance變量

            Public void methodA()   
            {

               synchronized(lock) { //… }

            }

            //…..

    }

    注:零長(zhǎng)度的byte數(shù)組對(duì)象創(chuàng)建起來(lái)將比任何對(duì)象都經(jīng)濟(jì)――查看編譯后的字節(jié)碼:生成零長(zhǎng)度的byte[]對(duì)象只需3條操作碼,而Object lock

    = new Object()則需要7行操作碼。

    3.將synchronized作用于static 函數(shù),示例代碼如下:

    Class Foo   
    {

        public synchronized static void methodAAA()   // 同步的static 函數(shù)   
        {    
            //….    
        }

        public void methodBBB()   
        {

           synchronized(Foo.class)   // class literal(類(lèi)名稱(chēng)字面常量)

        }   
    }

       代碼中的methodBBB()方法是把class literal作為鎖的情況,它和同步的static函數(shù)產(chǎn)生的效果是一樣的,取得的鎖很特別,是當(dāng)前調(diào)用這

    個(gè)方法的對(duì)象所屬的類(lèi)(Class,而不再是由這個(gè)Class產(chǎn)生的某個(gè)具體對(duì)象了)。

    記得在《Effective Java》一書(shū)中看到過(guò)將 Foo.class和 P1.getClass()用于作同步鎖還不一樣,不能用P1.getClass()來(lái)達(dá)到鎖這個(gè)Class的

    目的。P1指的是由Foo類(lèi)產(chǎn)生的對(duì)象。

    可以推斷:如果一個(gè)類(lèi)中定義了一個(gè)synchronized的static函數(shù)A,也定義了一個(gè)synchronized 的instance函數(shù)B,那么這個(gè)類(lèi)的同一對(duì)象Obj

    在多線程中分別訪問(wèn)A和B兩個(gè)方法時(shí),不會(huì)構(gòu)成同步,因?yàn)樗鼈兊逆i都不一樣。A方法的鎖是Obj這個(gè)對(duì)象,而B(niǎo)的鎖是Obj所屬的那個(gè)Class。

    小結(jié)如下:

    搞清楚synchronized鎖定的是哪個(gè)對(duì)象,就能幫助我們?cè)O(shè)計(jì)更安全的多線程程序。

    還有一些技巧可以讓我們對(duì)共享資源的同步訪問(wèn)更加安全:

    1. 定義private 的instance變量+它的 get方法,而不要定義public/protected的instance變量。如果將變量定義為public,對(duì)象在外界可以

    繞過(guò)同步方法的控制而直接取得它,并改動(dòng)它。這也是JavaBean的標(biāo)準(zhǔn)實(shí)現(xiàn)方式之一。

    2. 如果instance變量是一個(gè)對(duì)象,如數(shù)組或ArrayList什么的,那上述方法仍然不安全,因?yàn)楫?dāng)外界對(duì)象通過(guò)get方法拿到這個(gè)instance對(duì)象

    的引用后,又將其指向另一個(gè)對(duì)象,那么這個(gè)private變量也就變了,豈不是很危險(xiǎn)。 這個(gè)時(shí)候就需要將get方法也加上synchronized同步,并

    且,只返回這個(gè)private對(duì)象的clone()――這樣,調(diào)用端得到的就是對(duì)象副本的引用了

    posted @ 2012-08-29 17:47 japper 閱讀(344) | 評(píng)論 (0)編輯 收藏

    MyEclipse的一些配置及優(yōu)化

    MyEclipse的基礎(chǔ)配置:


    1. 先安裝MyEclipse,安裝MyEclipse7.5需要VPN代理,安裝過(guò)程大概持續(xù)10-15分鐘,使用VPN測(cè)試帳號(hào)即可

    2. 進(jìn)行MyEclipse的配置,
          從菜單欄中進(jìn)入“Windows --> Preferences”

    3. 先要進(jìn)行JDK的配置,
        在左側(cè)欄中選擇“Java --> Installed JREs”,
        按“Add”按鈕進(jìn)行添加

    4. 在彈出的“Add JRE”畫(huà)面中,選擇JRE的目錄,
        就是選擇你所在的JDK的目錄,我的為:C:\Program Files\Java\jre6
        在JRE名稱(chēng)一欄中,填下想取的名稱(chēng),我這里叫“HiJackson's JRE”,
        然后“OK”確定

    5. 返回到設(shè)置框中,將剛剛配置的JRE選中

    6. 將Tomcat Server設(shè)為可用,并設(shè)置Tomcat的安裝目錄

    7. 在Tomcat的JDK中選擇剛剛配置的JDK

    8. 配置完成了,三個(gè)地方可以啟動(dòng)它的服務(wù),根據(jù)自己的喜好吧~~~




     

     

    優(yōu)化MyEclipse:

    1、去除不需要加載的模塊

    一個(gè)系統(tǒng)20%的功能往往能夠滿足80%的需求,MyEclipse也不例外,我們?cè)诖蠖鄶?shù)時(shí)候只需要20%的系統(tǒng)功能,所以可以將一些不使用的模塊禁止 加載啟動(dòng)。通過(guò)Windows - Preferences打開(kāi)配置窗口,依次選擇左側(cè)的General - Startup and Shutdown,這個(gè)時(shí)候在右側(cè)就顯示出了Eclipse啟動(dòng)時(shí)加載的模塊,可以根據(jù)自己的實(shí)際情況去除一些模塊。
    windows–>perferences–>general–>startup and shutdown

    關(guān)掉沒(méi)用的啟動(dòng)項(xiàng):

    WTP :一個(gè)跟myeclipse差不多的東西,主要差別是 WTP 是免費(fèi)的,如果使用myeclipse,這個(gè)可以取消
    Mylyn:組隊(duì)任務(wù)管理工具,類(lèi)似于 CVS ,以任務(wù)為單位管理項(xiàng)目進(jìn)度,沒(méi)用到的可以取消
    Derby:一種保存成 jar 形式的數(shù)據(jù)庫(kù),我沒(méi)用到,取消
    一大排以 MyEclipse EASIE 打頭的啟動(dòng)項(xiàng):myeclipse 支持的服務(wù)器,只選自己用的,其他取消,比如我只選了tomcat6.x

    2、取消MyEclipse在啟動(dòng)時(shí)自動(dòng)驗(yàn)證項(xiàng)目配置文件

    默認(rèn)情況下MyEclipse在啟動(dòng)的時(shí)候會(huì)自動(dòng)驗(yàn)證每個(gè)項(xiàng)目的配置文件,這是一個(gè)非常耗時(shí)的過(guò)程,
    可以在Preferences窗口依次選擇 MyEclipse Enterprise Workbench - Validation,然后在右側(cè)的Validator列表中只保留 Manual 項(xiàng)就可以了(Manual全部勾選,Bulid項(xiàng)只留下第一項(xiàng))。
    如果需要驗(yàn)證的時(shí)候只需要選中文件,然后右鍵選擇 MyEclipse - Run Validation就可以了。

    windows–>perferences–>myeclipse–>validation
    把 除了manual 下面的全部點(diǎn)掉,build下只留 classpath dependency Validator

    手工驗(yàn)證方法:

    在要驗(yàn)證的文件上,單擊鼠標(biāo)右鍵–>myeclipse–>run validation


    3、去掉拼寫(xiě)檢查(如果你覺(jué)的有用可以不去)

    拼寫(xiě)檢查會(huì)給我們帶來(lái)不少的麻煩,我們的方法命名都會(huì)是單詞的縮寫(xiě),他也會(huì)提示有錯(cuò),所以最好去掉,沒(méi)有多大的用處:
    windows–>perferences–>general–>validation->editors->Text Editors->spelling

    myeclipse 打開(kāi) jsp 的默認(rèn)編輯器不好,會(huì)同時(shí)打開(kāi)預(yù)覽
    windows–>perferences–>general–>editors->file associations,

    把默認(rèn)改成 MyEclipse JSP Editor()
    原默認(rèn)的jsp編輯器是 MyEclipse Visual JSP Designer,顧名思義,此編譯器是jsp可視化編輯器,對(duì)于初學(xué)者有很多的幫助,
    但修改此項(xiàng)的默認(rèn)編輯器其實(shí)可以提高啟動(dòng)速度)

    4、關(guān)閉自動(dòng)更新

    如果是myeclipse7.5:

    (1)關(guān)掉maven自動(dòng)更新:

    window-preferences-MyEclipse Enterprise Workbench-Maven4MyEclipse-Maven,
    關(guān)閉所有Download和Update開(kāi)頭的選項(xiàng),共四項(xiàng)(去掉前面的勾)

    (2)關(guān)閉更新調(diào)度:window –> preferences –> General –> Startup and Shutdown –> Automatic Updates Scheduler(去掉前面的勾)

    (3)window –> preferences –>Myeclipse Dashboard,關(guān)閉Show……on start

    5、加大JVM的非堆內(nèi)存

    打開(kāi) myeclipse.ini
    -startup
    ../Common\plugins\org.eclipse.equinox.launcher_1.0.101.R34x_v20081125.jar
    --launcher.library
    ../Common\plugins\org.eclipse.equinox.launcher.win32.win32.x86_1.0.101.R34x_v20080731
    -clean
    -configuration
    configuration
    -vm
    C:\Users\lenovo\AppData\Local\Genuitec\Common\binary\com.sun.java.jdk.win32.x86_1.6.0.013\jre\bin\client\jvm.dll
    -vmargs
    -Xmx384m
    -XX:MaxPermSize=384m
    -XX:ReservedCodeCacheSize=96m

    以上是我的myeclipse.ini,需要修改是-Xmx,-XX:MaxPermSize,-XX:ReservedCodeCacheSize,
    將這三項(xiàng)的值調(diào)大,但并不是越大越好,曾經(jīng)在相同的條件下做過(guò)測(cè)試(內(nèi)存2GB),-Xmx,-XX:MaxPermSize的值為384m時(shí)比512m時(shí)要快(視具體的計(jì)算機(jī)而定),
    -Xmx,-XX:MaxPermSize的值設(shè)為同樣大小且兩者之和不能超出你的計(jì)算機(jī)本身的內(nèi)存大小

    6、window-preferences-MyEclipse Enterprise Workbench-Maven4MyEclipse-Maven,將Maven JDK改為電腦上安裝的JDK,即不使用myeclipse提高的JDK
    登記add按鈕,選擇你的電腦上的JDK即可(注意:不是JRE,我的值為:Java6.014)

    7、window-preferences-MyEclipse Enterprise Workbench-Matisse4Myeclipse/Swing,將Design-time information(dt.jar) location 改用電腦安裝的JDK的dt.jar
    (即不使用myeclipse提供的dt.jar,我的值為:C:\Java6.014\lib\dt.jar)

    經(jīng)過(guò)以上的優(yōu)化,myeclipse的啟動(dòng)時(shí)間可以減少2/3,Tomcat的啟動(dòng)速度可以減少1/2(視具體情況而定),

    特別6,7兩項(xiàng)的優(yōu)化效果最明顯,

    如果只進(jìn)行前5項(xiàng),優(yōu)化的效果有限,短期內(nèi)確實(shí)可以提高啟動(dòng)速度,但是大概半個(gè)月后又會(huì)變的很慢(具體原因不明)
    另外,使用myeclipse一段時(shí)間后,就會(huì)產(chǎn)生很多項(xiàng)目,即使這些項(xiàng)目是處于關(guān)閉狀態(tài),myecliose在啟動(dòng)時(shí)也會(huì)加載這些項(xiàng)目,這個(gè)過(guò)程會(huì)花費(fèi)很多時(shí)間,所以,建議將不用的項(xiàng)目都delete掉,用的時(shí)候再import

    在用[MyEclipse] 寫(xiě)代碼很容易卡死機(jī),尤其是在對(duì)JSP文件的﹤%%﹥之間寫(xiě)代碼的時(shí)候,只要一彈出智能提示就立刻卡死,程序失去響應(yīng),我以為是MyEclipse版本的問(wèn)題,結(jié)果換了6.0版-﹥6.5版-﹥7.0版全都一樣,難道是我機(jī)子的問(wèn)題?可是還原系統(tǒng)后用還是一樣的結(jié)果。

    百度一下你就知道,但是百度了N下才找到了一些門(mén)路,搜索也講究技巧,換了N個(gè)[關(guān)鍵字] 組合才搜出來(lái)。說(shuō)是MyEclipse在智能提示的時(shí)候自動(dòng)訪問(wèn)網(wǎng)絡(luò)上sun公司的最新API文檔,只要關(guān)閉掉網(wǎng)絡(luò)連接就可以了。我試了試斷開(kāi)網(wǎng)絡(luò)然后在用MyEclipse寫(xiě)代碼,結(jié)果還真的搞定了。可是,我總不能因?yàn)閭€(gè)這就不上網(wǎng)了吧,繼續(xù)接著百度,找到了兩全其美的解決方法。

    在自己創(chuàng)建的工程名上右鍵,選擇Properties--﹥?cè)诖蜷_(kāi)的窗口中點(diǎn)擊Java Build Path--﹥單擊Libraries選項(xiàng)卡,找到如圖中標(biāo)記2所示的地方--﹥選擇右邊的Remove更改成如標(biāo)記1所示的樣子--﹥點(diǎn)擊OK。


    posted @ 2012-07-20 10:25 japper 閱讀(1011) | 評(píng)論 (0)編輯 收藏

    jquery筆記0717

    1、不常用的切換函數(shù)$("p").toggle();當(dāng)點(diǎn)擊切換按鈕時(shí),隱藏元素為P行和顯示P行;

    <html>
    <head>
    <script type="text/javascript" src="/jquery/jquery.js"></script>
    <script type="text/javascript">
    $(document).ready(function(){
      $("button").click(function(){
      $("p").toggle();
      });
    });
    </script>
    </head>
    <body>
    <button type="button">切換</button>
    <p>This is a paragraph with little content.</p>
    <p>This is another small paragraph.</p>
    </body>
    </html>

    2、append() 函數(shù)向所匹配的 HTML 元素內(nèi)部追加內(nèi)容$(selector).append(content);
    <html>
    <head>
    <script type="text/javascript" src="/jquery/jquery.js"></script>
    <script type="text/javascript">
    $(document).ready(
    function(){
      $(
    "button").click(function(){
      $(
    "p").append(" <b>W3School</b>.");
      }
    );
    }
    );
    </script>
    </head>

    <body>
    <h2>This is a heading</h2>
    <p>This is a paragraph.</p>
    <p>This is another paragraph.</p>
    <button type="button">請(qǐng)點(diǎn)擊這里</button>
    </body>

    </html>
    類(lèi)似的還有:
    $(selector).html(content) 改變被選元素的(內(nèi)部)HTML
    $(selector).append(content) 向被選元素的(內(nèi)部)HTML 追加內(nèi)容
    $(selector).prepend(content) 向被選元素的(內(nèi)部)HTML “預(yù)置”(Prepend)內(nèi)容
    $(selector).after(content) 在被選元素之后添加 HTML
    $(selector).before(content) 在被選元素之前添加 HTML

    3、css操作:函數(shù) css({properties}) 同時(shí)為所有匹配元素的一系列 CSS 屬性設(shè)置值:
    $(selector).css({properties})
    $("p").css({"background-color":"red","font-size":"200%"});

    jQuery 擁有兩種用于尺寸操作的重要函數(shù):

    • $(selector).height(value)
    • $(selector).width(value)
    總結(jié)如:
    $(selector).css(name,value) 為匹配元素設(shè)置樣式屬性的值
    $(selector).css({properties}) 為匹配元素設(shè)置多個(gè)樣式屬性
    $(selector).css(name) 獲得第一個(gè)匹配元素的樣式屬性值
    $(selector).height(value) 設(shè)置匹配元素的高度
    $(selector).width(value) 設(shè)置匹配元素的寬度

    4、AJAX:

    jQuery AJAX 請(qǐng)求
    $(selector).load(url,data,callback) 把遠(yuǎn)程數(shù)據(jù)加載到被選的元素中
    $.ajax(options) 把遠(yuǎn)程數(shù)據(jù)加載到 XMLHttpRequest 對(duì)象中
    $.get(url,data,callback,type) 使用 HTTP GET 來(lái)加載遠(yuǎn)程數(shù)據(jù)
    $.post(url,data,callback,type) 使用 HTTP POST 來(lái)加載遠(yuǎn)程數(shù)據(jù)
    $.getJSON(url,data,callback) 使用 HTTP GET 來(lái)加載遠(yuǎn)程 JSON 數(shù)據(jù)
    $.getScript(url,callback) 加載并執(zhí)行遠(yuǎn)程的 JavaScript 文件

    (url) 被加載的數(shù)據(jù)的 URL(地址)

    (data) 發(fā)送到服務(wù)器的數(shù)據(jù)的鍵/值對(duì)象

    (callback) 當(dāng)數(shù)據(jù)被加載時(shí),所執(zhí)行的函數(shù)

    (type) 被返回的數(shù)據(jù)的類(lèi)型 (html,xml,json,jasonp,script,text)

    (options) 完整 AJAX 請(qǐng)求的所有鍵/值對(duì)選項(xiàng)

    略。。。


















    posted @ 2012-07-17 11:21 japper 閱讀(382) | 評(píng)論 (0)編輯 收藏

    使用jxl導(dǎo)出大數(shù)據(jù)量EXCEL時(shí)內(nèi)存溢出的解決辦法

    1、通過(guò)jx1最新版本的采用臨時(shí)文件寫(xiě)入EXCEL功能,設(shè)定臨時(shí)文件的位置,可以有效的避免內(nèi)存溢出:
                wbSetting.setUseTemporaryFileDuringWrite(true);   
                wbSetting.setTemporaryFileDuringWriteDirectory(new File(excelPath));//臨時(shí)文件夾的位置


    2、EXCEL獲取的list集合先讀取數(shù)據(jù)總行數(shù),再通過(guò)ROWNUM進(jìn)行控制,設(shè)定每次讀取多少行數(shù)據(jù),比如一個(gè)List設(shè)定為50000;
                WorkbookSettings wbSetting = new WorkbookSettings();   
                wbSetting.setUseTemporaryFileDuringWrite(true);   
                wbSetting.setTemporaryFileDuringWriteDirectory(new File(excelPath));//臨時(shí)文件夾的位置
                workbook = Workbook.createWorkbook(new File(fullPath),wbSetting);
                int returnCount=0;
                if(null!=pager)
                {
                    returnCount = BrasDatabase.getReturnCount(pager.getStartTime(),
                            pager.getEndTime(), pager);
                }

                if (returnCount > 0) {    
                    pager.setPageSize(50000);
                    pager.setTotalRows(returnCount);// 獲取總行數(shù)
                    pager.setNewTotalPages(pager.getTotalRows()); // 總頁(yè)數(shù)
                    for (int i = 1; i 
    <= pager.getTotalPages(); i++) {
                        pager.setCurrentPage(i); // 當(dāng)前頁(yè)面d
                        List<BrasAuth
    > list = BrasDatabase
                                .getBrasAuthResultByIpToExcelList(pager
                                        .getStartTime(), pager.getEndTime(), pager);
                        this.createExcel(list,excelFilePath);
                        list.clear();
                    }
                }



    3、在寫(xiě)入EXCEL的時(shí)候,將讀取的LIST分割,每50000條數(shù)據(jù)生成一個(gè)EXCEL的sheet(一個(gè)sheet最多能存儲(chǔ)60000多行數(shù)據(jù)),再寫(xiě)入,寫(xiě)入的時(shí)候,如果設(shè)置了采用臨時(shí)文件寫(xiě)入的話,jx1會(huì)自動(dòng)采用生成臨時(shí)文件的方式寫(xiě)入EXCEL:
            for(int i=1;i<=list.size();i++)
            {
                if(i%50000
    ==0)
                
    {
                    sheetName
    =format.format(new Date());
                    toExcel(list.subList(reNum, i),sheetName);
                    reNum
    =i;
                
    }
            }

    posted @ 2012-07-16 11:48 japper 閱讀(8905) | 評(píng)論 (1)編輯 收藏

    一個(gè)簡(jiǎn)單的分頁(yè)展示系統(tǒng)優(yōu)化總結(jié)

    由于開(kāi)發(fā)經(jīng)驗(yàn)較少,數(shù)據(jù)量較大(千萬(wàn)級(jí),日有40萬(wàn)條數(shù)據(jù)左右),導(dǎo)致這個(gè)分頁(yè)jsp頁(yè)面做的效率非常低,通過(guò)一系列的優(yōu)化后,效果明顯得到了提高,記錄一下筆記:
    1、分頁(yè)獲取的list對(duì)象集合由于沒(méi)有預(yù)料到數(shù)據(jù)量的大小,是直接一次性讀取然后展示到前臺(tái)的,導(dǎo)致查詢展示效率非常低:
    更改SQL語(yǔ)句,改為按照當(dāng)前需要展示的數(shù)據(jù)行數(shù),通過(guò)SQL的ROWNUM來(lái)進(jìn)行控制查詢的數(shù)據(jù)量大小,(插入數(shù)據(jù)時(shí),打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接即一次性插入100條數(shù)據(jù)(可以配置的模式)):
    SELECT BRAS_ADDRESS, APPLYTIMES, ALLFAILTIMES,SUCCESSRATE, RN 
    FROM 
    (SELECT BRAS_ADDRESS, APPLYTIMES, ALLFAILTIMES,SUCCESSRATE, ROWNUM AS RN 
    FROM 
    (SELECT BRAS_ADDRESS, APPLYTIMES, ALLFAILTIMES,
    1-ALLFAILTIMES/DECODE(APPLYTIMES,0,1,APPLYTIMES) AS SUCCESSRATE  
    FROM 
    (SELECT BRAS_ADDRESS, 
    SUM(DECODE(AUTNCOUNTTYPE,
    'REQ_CHALLENGE',APPLYTIMES,0)) AS APPLYTIMES, 
    SUM(DECODE(AUTNCOUNTTYPE,
    'ACK_CHALLENGE',APPLYTIMES,'ACK_AUTH',APPLYTIMES,'REQ_LOGOUT',APPLYTIMES,0)) AS ALLFAILTIMES 
    FROM T_BRAS_XXXX 
    WHERE READTIME between TO_DATE(
    '2012-06-01 00:00:00','yyyy-MM-dd HH24:mi:ss'
    and TO_DATE(
    '2012-06-12 23:59:59','yyyy-MM-dd HH24:mi:ss')
    GROUP BY BRAS_ADDRESS 
    )
    ORDER BY SUCCESSRATE

    WHERE  ROWNUM 
    <= 180 
    )
    WHERE RN 
    > 165 

    2、建立索引,建立索引的字段不能使用函數(shù)避免索引失效;
    3、建立分區(qū)表,將間隔5天的數(shù)據(jù)放在一個(gè)表中:


    ----------------------刪除原表,新建分區(qū)表
    --刪除表
    drop table T_BRAS_XXXX;
    commit;

    --創(chuàng)建分區(qū)表:利用Oracle11g INTERVAL進(jìn)行分區(qū)的方法
    create table T_BRAS_XXXX
    (
    BRAS_XXXX_ID integer NOT NULL PRIMARY KEY,
    BRAS_XXXX VARCHAR2(
    64),
    AUTNCOUNTTYPE VARCHAR2(
    50),
    SUCCESSTIMES NUMBER,
    APPLYTIMES NUMBER,
    INTERVALTIME NUMBER,
    UPDATETIME DATE  DEFAULT SYSDATE,
    READTIME DATE
    )
    PARTITION BY RANGE (READTIME)
    INTERVAL (NUMTODSINTERVAL(
    5,'day'))
    (
      PARTITION T_BRAS_XXXX_PART01 VALUES LESS THAN (TO_DATE(
    '2012-07-01 00:00:00','yyyy-MM-dd HH24:mi:ss'))
    )
    --保留原來(lái)創(chuàng)建的BRAS_XXXX_ID自增序列
    --創(chuàng)建索引
    create index idx_t_bras_XXXX on t_bras_XXXX(readtime,bras_address);
    commit;

    --查看分區(qū)是否成功:
    select table_name,partition_name from user_tab_partitions where table_name
    ='T_BRAS_XXXX';

    posted @ 2012-07-16 11:30 japper 閱讀(524) | 評(píng)論 (0)編輯 收藏

    ORACLE復(fù)制千萬(wàn)級(jí)數(shù)據(jù)表時(shí)用的存儲(chǔ)過(guò)程

    CREATE OR REPLACE PROCEDURE "LARGEDATA_INSERT" (ip_table_name   in varchar2, --目標(biāo)表
                                              ip_table_column in varchar2, --目標(biāo)字段
                                              ip_table_select in varchar2, --SELECT 查詢語(yǔ)句
                                              return_result   out number --返回的結(jié)果1,表示成功,0表示失敗
                                              ) as
    --適合大數(shù)據(jù)量的插入模板  create Templates by chenzhoumin 20110614
      runTime number;--運(yùn)行總次數(shù)
      i       number;--當(dāng)前行數(shù)
      amount  number;--總行數(shù)
      s_sql   varchar2(10000);--SQL語(yǔ)句
      e_sql   varchar2(10000);--執(zhí)行SQL語(yǔ)句
      countNumber number;--一次插入的數(shù)據(jù)量
    begin
      --set serveroutput on size 20000000000000
      countNumber := 10000;
      return_result := 0; --開(kāi)始初始化為0
      --核必邏輯內(nèi)容,可根據(jù)具體的業(yè)務(wù)邏輯來(lái)定義,統(tǒng)計(jì)數(shù)據(jù)總行數(shù)
      s_sql := 'select count(1) from (' || ip_table_select || ')';
      execute immediate s_sql
        into amount;
      --每100萬(wàn)提交一次
      runTime := amount mod countNumber;
      if (runTime > 0) then
        runTime := 1 + trunc(amount / countNumber);
      end if;
      if (runTime = 0) then
        runTime := 0 + trunc(amount / countNumber);
      end if;
      FOR i IN 1 .. runTime LOOP
        e_sql := 'insert into '||ip_table_name ||'
        ('||ip_table_column ||')
         select '|| ip_table_column ||'
         from
         (select selectSec.*, rownum rownumType
              from ('|| ip_table_select ||') selectSec
             WHERE ROWNUM <= '|| i * countNumber ||')
        WHERE rownumType > '||(i - 1) * countNumber;
        dbms_output.enable(99999999999999);
        dbms_output.put_line(e_sql);
        execute immediate e_sql;
        --提交
        commit;
      END LOOP;
      return_result := 1;
      return;
    exception
      when others then
        return_result := 0;
        raise;
        dbms_output.enable(99999999999999);
        dbms_output.put_line('結(jié)束');
        return;
    end;



    以上測(cè)試通過(guò)。

    posted @ 2012-07-09 15:06 japper 閱讀(1967) | 評(píng)論 (0)編輯 收藏

    ORACLE所在linux盤(pán)符空間不足的解決辦法

    ORACLE數(shù)據(jù)庫(kù)空間不足,會(huì)發(fā)生登錄出錯(cuò),數(shù)據(jù)無(wú)法插入等錯(cuò)誤發(fā)生,可以根據(jù)實(shí)際錯(cuò)誤代碼查詢?cè)颍贿^(guò)更多是平時(shí)多看看數(shù)據(jù)庫(kù)空間是否足夠;
    解決辦法有兩個(gè):
    1、使用linux命令或者工具增加空間或者增加硬盤(pán),沒(méi)有實(shí)際操作過(guò);
    2、給oracel數(shù)據(jù)庫(kù)增加系統(tǒng)表空間和臨時(shí)表空間,記錄下操作方法:

    如果臨時(shí)表空間或者SYSTEM表空間不足,可以進(jìn)行新增數(shù)據(jù)文件到其它盤(pán)符(增加opt盤(pán)符目錄):
    select ts#, name from v$datafile;--查看當(dāng)前的表空間狀況
    select * from database_properties where property_name='DEFAULT_TEMP_TABLESPACE';--查看默認(rèn)的臨時(shí)文件
    create temporary tablespace temp2 tempfile '/opt/oracle/oracle_tmp/temp02.dbf' size 5000M autoextend on next 100M; --新增臨時(shí)文件
    alter database default temporary tablespace "TEMP2";  --修改默認(rèn)臨時(shí)文件設(shè)置
    alter database tempfile '/home/oracle/oracle/oradata/portal/temp01.dbf' autoextend off;  --關(guān)閉原來(lái)的臨時(shí)文件自增長(zhǎng)
    增加系統(tǒng)表空間:
    alter tablespace SYSTEM add datafile '/opt/oracle/oracle_tmp/system02.dbf' size 500M autoextend on next 5M;

    如果startup數(shù)據(jù)庫(kù)時(shí),提示:prifile文件找不到,可以從一個(gè)$ORACLE_BASE/admin/portal/pfile目錄下拷貝內(nèi)容過(guò)去就可以(注意文件命名和原來(lái)使用的保持一樣,只是內(nèi)容不同):
    當(dāng)前正在使用的pfile:startup force pfile='/home/oracle/oracle/product/11.0.1/db_1/dbs/initportal.ora';
    拷貝:cp $ORACLE_BASE/admin/portal/pfile/init.ora.452011185827   /home/oracle/oracle/product/11.0.1/db_1/dbs/spfileportal.ora

    posted @ 2012-07-02 14:14 japper 閱讀(1323) | 評(píng)論 (0)編輯 收藏

    oracle 臨時(shí)表空間的增刪改查

    oracle 臨時(shí)表空間的增刪改查

    1、查看臨時(shí)表空間 (dba_temp_files視圖)(v_$tempfile視圖)
    select tablespace_name,file_name,bytes/1024/1024 file_size,autoextensible from dba_temp_files;
    select status,enabled, name, bytes/1024/1024 file_size from v_$tempfile;--sys用戶查看

    2、縮小臨時(shí)表空間大小
    alter database tempfile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\TELEMT\TEMP01.DBF' resize 100M;

    3、擴(kuò)展臨時(shí)表空間:
    方法一、增大臨時(shí)文件大小:
    SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ resize 100m;
    方法二、將臨時(shí)數(shù)據(jù)文件設(shè)為自動(dòng)擴(kuò)展:
    SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ autoextend on next 5m maxsize unlimited;
    方法三、向臨時(shí)表空間中添加數(shù)據(jù)文件:
    SQL> alter tablespace temp add tempfile ‘/u01/app/oracle/oradata/orcl/temp02.dbf’ size 100m;

    4、創(chuàng)建臨時(shí)表空間
    SQL> create temporary tablespace temp1 tempfile ‘/u01/app/oracle/oradata/orcl/temp11.dbf’ size 10M;

    5、更改系統(tǒng)的默認(rèn)臨時(shí)表空間:
    --查詢默認(rèn)臨時(shí)表空間
    select * from database_properties where property_name='DEFAULT_TEMP_TABLESPACE';
    --修改默認(rèn)臨時(shí)表空間
    alter database default temporary tablespace temp1;
    所有用戶的默認(rèn)臨時(shí)表空間都將切換為新的臨時(shí)表空間:
    select username,temporary_tablespace,default_ from dba_users;
    --更改某一用戶的臨時(shí)表空間:
    alter user scott temporary tablespace temp;

    6、刪除臨時(shí)表空間
    刪除臨時(shí)表空間的一個(gè)數(shù)據(jù)文件:
    SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp02.dbf’ drop;
    刪除臨時(shí)表空間(徹底刪除):
    SQL> drop tablespace temp1 including contents and datafiles cascade constraints;

    7、查看臨時(shí)表空間的使用情況(GV_$TEMP_SPACE_HEADER視圖必須在sys用戶下才能查詢)
    GV_$TEMP_SPACE_HEADER視圖記錄了臨時(shí)表空間的使用大小與未使用的大小
    dba_temp_files視圖的bytes字段記錄的是臨時(shí)表空間的總大小
    SELECT temp_used.tablespace_name,
           total - used as "Free",
           total as "Total",
           round(nvl(total - used, 0) * 100 / total, 3) "Free percent"
      FROM (SELECT tablespace_name, SUM(bytes_used) / 1024 / 1024 used
              FROM GV_$TEMP_SPACE_HEADER
             GROUP BY tablespace_name) temp_used,
           (SELECT tablespace_name, SUM(bytes) / 1024 / 1024 total
              FROM dba_temp_files
             GROUP BY tablespace_name) temp_total
     WHERE temp_used.tablespace_name = temp_total.tablespace_name

    8、查找消耗資源比較的sql語(yǔ)句
    Select se.username,
           se.sid,
           su.extents,
           su.blocks * to_number(rtrim(p.value)) as Space,
           tablespace,
           segtype,
           sql_text
      from v$sort_usage su, v$parameter p, v$session se, v$sql s
     where p.name = 'db_block_size'
       and su.session_addr = se.saddr
       and s.hash_value = su.sqlhash
       and s.address = su.sqladdr
     order by se.username, se.sid
     
    9、查看當(dāng)前臨時(shí)表空間使用大小與正在占用臨時(shí)表空間的sql語(yǔ)句
    select sess.SID, segtype, blocks * 8 / 1000 "MB", sql_text
      from v$sort_usage sort, v$session sess, v$sql sql
     where sort.SESSION_ADDR = sess.SADDR
       and sql.ADDRESS = sess.SQL_ADDRESS
     order by blocks desc;

    10、臨時(shí)表空間組介紹
      1)創(chuàng)建臨時(shí)表空間組:
    create temporary tablespace tempts1 tempfile '/home/oracle/temp1_02.dbf' size 2M tablespace group group1;
    create temporary tablespace tempts2 tempfile '/home/oracle/temp2_02.dbf' size 2M tablespace group group2;
     
     2)查詢臨時(shí)表空間組:dba_tablespace_groups視圖
    select * from dba_tablespace_groups;
    GROUP_NAME                     TABLESPACE_NAME
    ------------------------------ ------------------------------
    GROUP1                         TEMPTS1
    GROUP2                         TEMPTS2

     3)將表空間從一個(gè)臨時(shí)表空間組移動(dòng)到另外一個(gè)臨時(shí)表空間組:
    alter tablespace tempts1 tablespace group GROUP2 ;
    select * from dba_tablespace_groups;

    GROUP_NAME                     TABLESPACE_NAME
    ------------------------------ ------------------------------
    GROUP2                         TEMPTS1
    GROUP2                         TEMPTS2

     4)把臨時(shí)表空間組指定給用戶
    alter user scott temporary tablespace GROUP2;

     5)在數(shù)據(jù)庫(kù)級(jí)設(shè)置臨時(shí)表空間
    alter database <db_name> default temporary tablespace GROUP2;

     6)刪除臨時(shí)表空間組 (刪除組成臨時(shí)表空間組的所有臨時(shí)表空間)
    drop tablespace tempts1 including contents and datafiles;
    select * from dba_tablespace_groups;
    GROUP_NAME                     TABLESPACE_NAME
    ------------------------------ ------------------------------
    GROUP2                         TEMPTS2

    drop tablespace tempts2 including contents and datafiles;
    select * from dba_tablespace_groups;
    GROUP_NAME                     TABLESPACE_NAME

    11、對(duì)臨時(shí)表空間進(jìn)行shrink(11g新增的功能)
    --將temp表空間收縮為20M
    alter tablespace temp shrink space keep 20M;
    --自動(dòng)將表空間的臨時(shí)文件縮小到最小可能的大小
    ALTER TABLESPACE temp SHRINK TEMPFILE ’/u02/oracle/data/lmtemp02.dbf’;

    臨時(shí)表空間作用
    Oracle臨時(shí)表空間主要用來(lái)做查詢和存放一些緩沖區(qū)數(shù)據(jù)。臨時(shí)表空間消耗的主要原因是需要對(duì)查詢的中間結(jié)果進(jìn)行排序。
    重啟數(shù)據(jù)庫(kù)可以釋放臨時(shí)表空間,如果不能重啟實(shí)例,而一直保持問(wèn)題sql語(yǔ)句的執(zhí)行,temp表空間會(huì)一直增長(zhǎng)。直到耗盡硬盤(pán)空間。
    網(wǎng)上有人猜測(cè)在磁盤(pán)空間的分配上,oracle使用的是貪心算法,如果上次磁盤(pán)空間消耗達(dá)到1GB,那么臨時(shí)表空間就是1GB。
    也就是說(shuō)當(dāng)前臨時(shí)表空間文件的大小是歷史上使用臨時(shí)表空間最大的大小。

    臨時(shí)表空間的主要作用:
      索引create或rebuild;
      Order by 或 group by;
      Distinct 操作;
      Union 或 intersect 或 minus;
      Sort-merge joins;
      analyze.

    posted @ 2012-06-28 14:54 japper 閱讀(31508) | 評(píng)論 (2)編輯 收藏

    在JQuery中使用jsp頁(yè)面的select事件

    JQuery中的select事件是change事件,在js中使用的是onchange事件:
    <script src="jquery.min.js" type="text/javascript"></script> 
    <script language="javascript" type="text/javascript"> 
    $(document).ready(function()

    $(
    '#mySelect').change(function()
    alert($(
    this).children('option:selected').val()); 
    var p1
    =$(this).children('option:selected').val();//這就是selected的值 
    var p2=$('#param2').val();//獲取本頁(yè)面其他標(biāo)簽的值 
    window.location.href="xx.php?param1="+p1+"¶m2="+p2+"";//頁(yè)面跳轉(zhuǎn)并傳參 
     }

    }

    </script> 

    <select id="mySelect"> 
    <option value="1">one</option> 
    <option value="2" selected="selected">two</option> 
    <option value="3">three</option> 
    </select> 

    又如:

           $(document).ready
           (
            function()
            {  
            $("#showLoadingDiv").click(function(){$("#dataLoad").show();}); //為指定按鈕添加數(shù)據(jù)加載動(dòng)態(tài)顯示:即將DIV顯示出來(lái)
            $("#orderByFail").click(function(){$("#dataLoad").show();});
            $("#orderByRate").click(function(){$("#dataLoad").show();});
            $("#stats").change(function(){$("#dataLoad").show();}); //change
            $("#indexPage").click(function(){$("#dataLoad").show();});
            }
           );


                  <select name="dictFilter.dictStatus" id="stats" onchange="javascript:location.href=this.value">
                  <option selected="selected" value="<%=basePath%>acauthinfo/authDefault.jsp?pageNum=1&StartTime=<%=pager.getStartTime()%>&field=<%=pager.getField()%>&sortOrder=<%=pager.getSortOrder()%>&EndTime=<%=pager.getEndTime()%>&pageSize=10" >每頁(yè)10行</option>
                  <option selected="selected" value="<%=basePath%>acauthinfo/authDefault.jsp?pageNum=1&StartTime=<%=pager.getStartTime()%>&field=<%=pager.getField()%>&sortOrder=<%=pager.getSortOrder()%>&EndTime=<%=pager.getEndTime()%>&pageSize=20">每頁(yè)20行</option>
                  <option selected="selected" value="<%=basePath%>acauthinfo/authDefault.jsp?pageNum=1&StartTime=<%=pager.getStartTime()%>&field=<%=pager.getField()%>&sortOrder=<%=pager.getSortOrder()%>&EndTime=<%=pager.getEndTime()%>&pageSize=30">每頁(yè)30行</option>
                  <option selected="selected" value="">---請(qǐng)選擇---</option>
                  </select>

    posted @ 2012-06-15 14:52 japper 閱讀(2169) | 評(píng)論 (0)編輯 收藏

    測(cè)試JAVA中SELECT COUNT(*) FROM XXX得到的ResultSet行數(shù)

    初學(xué)的知識(shí),怕忘記了,記錄下:
        /**
         *  測(cè)試SELECT COUNT(*)返回int類(lèi)型的數(shù)據(jù)
         
    */


        
    public static int testRturnNumber()
        
    {
            
    int number=0;
            
    int number1=0;
            Connection conn 
    = DBUtils.getConn();
            Statement stmt
    =null;
            
    try{
            stmt 
    = conn.createStatement();
            String strSQL
    ="select count(*)as num from t_bras_authinfo"
            ResultSet rs 
    = stmt.executeQuery(strSQL);        

            
    if(null!=rs)
            
    {
                
    while(rs.next())
                
    {
                    number
    =rs.getInt("num"); //通過(guò)指定別名返回行數(shù)
                    number1=rs.getInt(1); //通過(guò)索引返回行數(shù)
                }

            }


        }

            
    catch(Exception e)
            
    {
                logger4sdk
                .debug(
    "[delLastMonthData] delete t_bras_authinfo faile : "
                        
    +e.getMessage());   
                
    return number;
            }

            
    finally
            
    {
                DBUtils.close(conn, stmt, 
    null) ;
            }

            
    return number;
        }

    在主方法中執(zhí)行:
       BrasDatabase bd=new BrasDatabase();
       int returnNum=bd.testRturnNumber();
       System.out.println("返回總行數(shù):"+returnNum);

    以上兩種方式都可以正常返回行數(shù)。

    posted @ 2012-06-07 11:24 japper 閱讀(3586) | 評(píng)論 (0)編輯 收藏

    來(lái)點(diǎn)HTML基礎(chǔ)-HTML表單(Forms)屬性及用法

    HTML表單(Form)是HTML的一個(gè)重要部分,主要用于采集和提交用戶輸入的信息。

    舉個(gè)簡(jiǎn)單的例子,一個(gè)讓用戶輸入姓名的HTML表單(Form)。示例代碼如下:

    <form action="

    請(qǐng)輸入你的姓名:

    <input type="text" name="yourname">

    <input type="submit" value="提交">

    </form>

    學(xué)習(xí)HTML表單(Form)最關(guān)鍵要掌握的有三個(gè)要點(diǎn):

    表單控件(Form Controls)
    Action
    Method
    先說(shuō)表單控件(Form Controls),通過(guò)HTML表單的各種控件,用戶可以輸入文字信息,或者從選項(xiàng)中選擇,以及做提交的操作。比如上面的例句里,input type= "text"就是一個(gè)表單控件,表示一個(gè)單行輸入框。

    用戶填入表單的信息總是需要程序來(lái)進(jìn)行處理,表單里的action就指明了處理表單信息的文件。比如上面例句里的http://www.linkzj.cn/asdocs/html_tutorials/yourname.asp

    至于method,表示了發(fā)送表單信息的方式。method有兩個(gè)值:get和post。get的方式是將表單控件的name/value信息經(jīng)過(guò)編碼之后,通過(guò)URL發(fā)送(你可以在地址欄里看到)。而post則將表單的內(nèi)容通過(guò)http發(fā)送,你在地址欄看不到表單的提交信息。那什么時(shí)候用get,什么時(shí)候用post呢?一般是這樣來(lái)判斷的,如果只是為取得和顯示數(shù)據(jù),用get;一旦涉及數(shù)據(jù)的保存和更新,那么建議用post。

    HTML表單(Form)常用控件(Controls)
    HTML表單(Form)常用控件有:

    input type="text" 單行文本輸入框
    input type="submit" 將表單(Form)里的信息提交給表單里action所指向的文件
    input type="checkbox" 復(fù)選框
    input type="radio" 單選框
    select 下拉框
    textArea 多行文本輸入框
    input type="password" 密碼輸入框(輸入的文字用*表示)
    表單控件(Form Control):?jiǎn)涡形谋据斎肟?input type="text")
    單行文本輸入框允許用戶輸入一些簡(jiǎn)短的單行信息,比如用戶姓名
    。例句如下:

    <input type="text" name="yourname">

    表單控件(Form Control):
    復(fù)選框(input type="checkbox")
    復(fù)選框允許用戶在一組選項(xiàng)里,選擇多個(gè)。示例代碼:

    <input type="checkbox" name="fruit" value ="apple">蘋(píng)果<br>

    <input type="checkbox" name="fruit" value ="orange">桔子<br>

    <input type="checkbox" name="fruit" value ="mango">芒果<br>

    用checked表示缺省已選的選項(xiàng)。

    <input type="checkbox" name="fruit" value ="orange" checked>桔子<br>

    表單控件(Form Control):?jiǎn)芜x框(input type="radio")
    使用單選框,讓用戶在一組選項(xiàng)里只能選擇一個(gè)。示例代碼:

    <input type="radio" name="fruit" value = "Apple">蘋(píng)果<br>

    <input type="radio" name="fruit" value = "Orange">桔子<br>

    <input type="radio" name="fruit" value = "Mango">芒果<br>

    用checked表示缺省已選的選項(xiàng)。

    <input type="radio" name="fruit" value = "Orange" checked>桔子<br>

    表單控件(Form Control):下拉框(select)
    下拉框(Select)既可以用做單選,也可以用做復(fù)選。單選例句如下:

    <select name="fruit" >

    <option value="apple">蘋(píng)果

    <option value="orange">桔子

    <option value="mango">芒果

    </select>

    如果要變成復(fù)選,加muiltiple即可。用戶用Ctrl來(lái)實(shí)現(xiàn)多選。例句:

    <select name="fruit" multiple>

    用戶還可以用size屬性來(lái)改變下拉框(Select)的大小。

    表單控件(Form Control):多行輸入框(textarea)
    多行輸入框(textarea)主要用于輸入較長(zhǎng)的文本信息。例句如下:

    <textarea name="yoursuggest" cols ="50" rows = "3"></textarea>

    其中cols表示textarea的寬度,rows表示textarea的高度。

    表單控件(Form Control):密碼輸入框(input type="password")
    密碼輸入框(input type="password")主要用于一些保密信息的輸入,比如密碼。因?yàn)橛脩糨斎氲臅r(shí)候,顯示的不是輸入的內(nèi)容,而是黑點(diǎn)符號(hào)。。例句如下:

    <input type="password" name="yourpw">

    表單控件(Form Control):提交(input type="submit")
    通過(guò)提交(input type=submit)可以將表單(Form)里的信息提交給表單里action所指向的文件。例句如下:

    <input type="submit" value="提交">

    表單控件(Form Control):圖片提交(input type="image")
    input type=image 相當(dāng)于 input type=submit,不同的是,input type=image 以一個(gè)圖片作為表單的提交按鈕,其中 src 屬性表示圖片的路徑。

    <input type="image" src ="

    posted @ 2012-06-07 09:29 japper 閱讀(916) | 評(píng)論 (0)編輯 收藏

    GET和POST兩種提交表單的方式說(shuō)明

    1.Get方式
    這種方式是最簡(jiǎn)單的參數(shù)傳遞方式。例如:
    http://www.javaweb.cc/get.do?a=3&b=5&c=7

    這個(gè)url中,a、b和c是url參數(shù),具體的說(shuō)是參數(shù)名,與之用“=”隔開(kāi)的是對(duì)應(yīng)的參數(shù)值。也就是說(shuō)參數(shù)a的值為3、參數(shù)b的值為5、參數(shù)c的值為7。get.do是請(qǐng)求地址,緊跟這個(gè)地址的參數(shù)a需要用“?”作為分隔符,其余參數(shù)用“&”做分隔符。

    這種get請(qǐng)求發(fā)起后,服務(wù)器端可以通過(guò)request.getParameter()方法來(lái)獲得參數(shù)值。如要獲得參數(shù)a的值可以通過(guò)request.getParameter("a");


    2.Post方式
    相比get方式,post方式更為隱蔽。例如:http://www.javaweb.cc/post.do
    在這個(gè)url中,你看不到任何參數(shù),真正的參數(shù)隱藏在Http請(qǐng)求的數(shù)據(jù)體中。如果了解網(wǎng)絡(luò)監(jiān)聽(tīng)的話,就會(huì)對(duì)這一點(diǎn)深有體會(huì)。
    我們舉一個(gè)簡(jiǎn)單的例子:通過(guò)表單做登錄操作。
    我們簡(jiǎn)化一個(gè)登錄表單:

    <form action="login.do" method="post">
    <ul>
    <li><label for="username">用戶名</label><input id="username" name="username" type="text" /></li>
    <li><label for="password">密碼</label><input id="password" type="password" /></li>
    <li><label><input type="submit" value="登錄" /> <input
    type="reset" value="重置" /></label></li>
    </ul>
    </form>
    表單中有2個(gè)字段,用戶名(username)和密碼(password)
    注意form標(biāo)簽中的method參數(shù)值是post!

    即便是表單,在服務(wù)器端仍然可以通過(guò)request.getParameter()方法來(lái)獲得參數(shù)值。
    Post方式,其實(shí)是將表單字段和經(jīng)過(guò)編碼的字段值經(jīng)過(guò)組合以數(shù)據(jù)體的方式做了參數(shù)傳遞。

    經(jīng)過(guò)一番闡述,相信大家對(duì)兩種網(wǎng)絡(luò)參數(shù)傳遞方式都有所了解了。
    Get方式比較簡(jiǎn)單,通過(guò)構(gòu)建一個(gè)簡(jiǎn)單HttpURLConnection就可以獲得,我們暫且不說(shuō)。
    我們主要來(lái)描述一下如何通過(guò)java代碼構(gòu)建一個(gè)表單提交。
    仔細(xì)研究表單提交時(shí)所對(duì)應(yīng)的http數(shù)據(jù)體,發(fā)現(xiàn)其表單字段是以如下方式構(gòu)建的:

    arg0=urlencode(value0)&arg1=urlencode(value1)
    當(dāng)然,尤其要注意字段名,參數(shù)名只不能使用中文這類(lèi)字符。
    3、通過(guò)httpclient來(lái)模擬POST提交表單:


    import java.util.Random;
    import java.util.ArrayList;
    import java.util.List;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.cookie.Cookie;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.protocol.HTTP;
    import org.apache.http.util.EntityUtils;

    /**
     * Example how to use multipart/form encoded POST request.
     
    */

    public class ClientMultipartFormPost {



        
    public static void ExecuClient(String userName, String wlanuserip2,
                String wlanacip2) 
    throws Exception {
            DefaultHttpClient httpclient 
    = new DefaultHttpClient();
            String a1
    ="http://172.21.16.38:8080/bpss/jsp/do_login.jsp";
            
    try {
                HttpGet httpget 
    = new HttpGet(a1);
                HttpResponse response 
    = httpclient.execute(httpget);
                HttpEntity entity 
    = response.getEntity();
                System.out.println(
    "Login form get: " + response.getStatusLine());
                EntityUtils.consume(entity);
                
    //這里需要生成并傳遞一個(gè)COOKIE過(guò)去
                System.out.println("Initial set of cookies:");
                List
    <Cookie> cookies = httpclient.getCookieStore().getCookies();
                
    if (cookies.isEmpty()) {
                    System.out.println(
    "None");
                }
     else {
                    
    for (int i = 0; i < cookies.size(); i++{
                        System.out.println(
    "" + cookies.get(i).toString());
                    }

                }

                HttpPost httppost 
    = new HttpPost(a1);

                List
    <NameValuePair> nvps = new ArrayList<NameValuePair>();
                nvps.add(
    new BasicNameValuePair("local""zh_CN"));
                nvps.add(
    new BasicNameValuePair("USER", userName));
                nvps.add(
    new BasicNameValuePair("PWD""123456"));
                nvps.add(
    new BasicNameValuePair("pwdtype""1"));
                nvps.add(
    new BasicNameValuePair("actiontype""LOGIN"));
                nvps.add(
    new BasicNameValuePair("logonsessid"""));

                httppost.setEntity(
    new UrlEncodedFormEntity(nvps, HTTP.UTF_8));

                response 
    = httpclient.execute(httppost);
                entity 
    = response.getEntity();
                System.out.println(
    "測(cè)試地址: " + a1);
                System.out.println(
    "Login form get: " + response.getStatusLine());
                EntityUtils.consume(entity);
                
                
    //讀出COOKIE信息
                System.out.println("Post logon cookies:");
                cookies 
    = httpclient.getCookieStore().getCookies();
                
    if (cookies.isEmpty()) {
                    System.out.println(
    "None");
                }
     else {
                    
    for (int i = 0; i < cookies.size(); i++{
                        System.out.println(
    "" + cookies.get(i).toString());
                    }

                }


            }
     finally {
                
    try {
                    httpclient.getConnectionManager().shutdown();
    // 總是關(guān)閉連接
                }
     catch (Exception ignore) {
                    System.out.println(ignore.getMessage());
                }

            }

        }


    posted @ 2012-06-06 17:09 japper 閱讀(4468) | 評(píng)論 (1)編輯 收藏

    表單提交的幾種方式

      1、<!--通用提交按鈕-->
      <input type="submit" value="提交">
      2、<!--自定義提交按鈕-->
      <button type="Submit">提交</button>
      3、<!--圖像按鈕-->
      <input type="image" src = "btn.png">
    說(shuō)明:用戶提交按鈕或圖像按鈕時(shí),就會(huì)提交表單。使用<input>或<button>都可以定義提交按鈕,只要將其特性的值設(shè)置為“submit”即可,而圖像按鈕則是通過(guò)<input>的type特性值設(shè)置為”image”來(lái)定義的。因此,只要我們單擊一下代碼生成的按鈕,就可以提交表單。

        4、阻止表單提交

    只要在表單中存在上面列出的任何一種按鈕,那么相應(yīng)表單控件擁有焦點(diǎn)的情況下,按回車(chē)鍵就可以提交表單。如果表單里沒(méi)有提交按鈕,按回車(chē)鍵不會(huì)提交表單。

      以這種方式提交表單時(shí),瀏覽器會(huì)在將請(qǐng)求發(fā)送給服務(wù)器之前觸發(fā)submit事件。這樣,我們就有機(jī)會(huì)驗(yàn)證表單數(shù)據(jù),并據(jù)以決定是否允許表單提交。阻止這個(gè)事件的默認(rèn)行為就可以取消表單提交。例如,下面代碼會(huì)阻止表單提交:

    var EventUtil = {
        addHandler: function (element, type, handler) {
            if (element.addEventListener) {
                element.addEventListener(type, handler, false);
            } else if (element.attachEvent) {
                element.attachEvent("on" + type, handler);
            } else {
                element["on" + type] = handler;
            }
        },
        getEvent: function (event) {
            return event ? event : window.event;
        },
        preventDefault: function (event) {
            if (event.preventDefault) {
                event.preventDefault();
            } else {
                event.returnValue = false;
            }
        }

    };

    var form = document.getElementById("myForm");
    EventUtil.addHandler(form, "submit", function () {
        //取得事件對(duì)象
        event = EventUtil.getEvent(event);
        //阻止默認(rèn)事件
        EventUtil.preventDefault(event);
    });  
    調(diào)用preventDefault()方法阻止了表單提交。一般來(lái)說(shuō),在表單數(shù)據(jù)無(wú)效而不能發(fā)送給服務(wù)器時(shí),可以使用這一技術(shù)。

    5、在JavaScript中,以編程方式調(diào)用submit()方法也可以提交表單。
        
    這種方式無(wú)需表單包含提交按鈕,任何時(shí)候都可以正常提交表單。來(lái)看一個(gè)例子:

      var form = document.getElementById("myForm");
      //提交表單
      form.submit();  
         在以調(diào)用submit()方法的形式提交表單時(shí),不會(huì)觸發(fā)submit事件,因此要記得在調(diào)用此方法之前先驗(yàn)證表單數(shù)字據(jù)。

      提交表單時(shí)可能出現(xiàn)的最大問(wèn)題,就是重復(fù)提交表單。在第一次提交表單后,如果長(zhǎng)時(shí)間沒(méi)有反映,用戶可能會(huì)變得不耐煩。這時(shí)候,他們也許會(huì)反復(fù)單擊提交按鈕。結(jié)果往往很麻煩(因?yàn)榉?wù)器要處理重復(fù)請(qǐng)求),或者造成錯(cuò)誤(如果是下了訂單,那么可能會(huì)多定好幾份)。
    解決這一問(wèn)題的辦法有兩個(gè):
         在第一次提交表單后就禁用提交按鈕;
         利用onsubmit事件處理程序取消后續(xù)的表單提交操作。

     

    posted @ 2012-06-06 10:16 japper 閱讀(11105) | 評(píng)論 (7)編輯 收藏

    java的System.getProperty()方法可以獲取的值

    java.version

    Java 運(yùn)行時(shí)環(huán)境版本

    java.vendor

    Java 運(yùn)行時(shí)環(huán)境供應(yīng)商

    java.vendor.url

    Java 供應(yīng)商的 URL

    java.home

    Java 安裝目錄

    java.vm.specification.version

    Java 虛擬機(jī)規(guī)范版本

    java.vm.specification.vendor

    Java 虛擬機(jī)規(guī)范供應(yīng)商

    java.vm.specification.name

    Java 虛擬機(jī)規(guī)范名稱(chēng)

    java.vm.version

    Java 虛擬機(jī)實(shí)現(xiàn)版本

    java.vm.vendor

    Java 虛擬機(jī)實(shí)現(xiàn)供應(yīng)商

    java.vm.name

    Java 虛擬機(jī)實(shí)現(xiàn)名稱(chēng)

    java.specification.version

    Java 運(yùn)行時(shí)環(huán)境規(guī)范版本

    java.specification.vendor

    Java 運(yùn)行時(shí)環(huán)境規(guī)范供應(yīng)商

    java.specification.name

    Java 運(yùn)行時(shí)環(huán)境規(guī)范名稱(chēng)

    java.class.version

    Java 類(lèi)格式版本號(hào)

    java.class.path

    Java 類(lèi)路徑

    java.library.path

    加載庫(kù)時(shí)搜索的路徑列表

    java.io.tmpdir

    默認(rèn)的臨時(shí)文件路徑

    java.compiler

    要使用的 JIT 編譯器的名稱(chēng)

    java.ext.dirs

    一個(gè)或多個(gè)擴(kuò)展目錄的路徑

    os.name

    操作系統(tǒng)的名稱(chēng)

    os.arch

    操作系統(tǒng)的架構(gòu)

    os.version

    操作系統(tǒng)的版本

    file.separator

    文件分隔符(在 UNIX 系統(tǒng)中是“/”)

    path.separator

    路徑分隔符(在 UNIX 系統(tǒng)中是“:”)

    line.separator

    行分隔符(在 UNIX 系統(tǒng)中是“/n”)

    user.name

    用戶的賬戶名稱(chēng)

    user.home

    用戶的主目錄

    user.dir

    用戶的當(dāng)前工作目錄



    獲取的代碼示例:


    01.public class SystemProperty { 
    02.    public static void main(String args[]) {    
    03.    System.out.println("java_vendor:" + System.getProperty("java.vendor"));    
    04.    System.out.println("java_vendor_url:"    
    05.             + System.getProperty("java.vendor.url"));    
    06.    System.out.println("java_home:" + System.getProperty("java.home"));    
    07.    System.out.println("java_class_version:"    
    08.             + System.getProperty("java.class.version"));    
    09.    System.out.println("java_class_path:"    
    10.            + System.getProperty("java.class.path"));    
    11.    System.out.println("os_name:" + System.getProperty("os.name"));    
    12.    System.out.println("os_arch:" + System.getProperty("os.arch"));    
    13.    System.out.println("os_version:" + System.getProperty("os.version"));    
    14.    System.out.println("user_name:" + System.getProperty("user.name"));    
    15.    System.out.println("user_home:" + System.getProperty("user.home"));    
    16.    System.out.println("user_dir:" + System.getProperty("user.dir"));    
    17.    System.out.println("java_vm_specification_version:"    
    18.            + System.getProperty("java.vm.specification.version"));    
    19.    System.out.println("java_vm_specification_vendor:"    
    20.            + System.getProperty("java.vm.specification.vendor"));    
    21.    System.out.println("java_vm_specification_name:"    
    22.            + System.getProperty("java.vm.specification.name"));    
    23.    System.out.println("java_vm_version:"    
    24.            + System.getProperty("java.vm.version"));    
    25.    System.out.println("java_vm_vendor:"    
    26.            + System.getProperty("java.vm.vendor"));    
    27.    System.out    
    28.            .println("java_vm_name:" + System.getProperty("java.vm.name"));    
    29.    System.out.println("java_ext_dirs:"    
    30.            + System.getProperty("java.ext.dirs"));    
    31.    System.out.println("file_separator:"    
    32.            + System.getProperty("file.separator"));    
    33.    System.out.println("path_separator:"    
    34.            + System.getProperty("path.separator"));    
    35.    System.out.println("line_separator:"    
    36.            + System.getProperty("line.separator"));    
    37.}    





    posted @ 2012-06-05 17:27 japper 閱讀(553) | 評(píng)論 (0)編輯 收藏

    checkStyle配置說(shuō)明、范例和結(jié)果分析

         摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->  1<?xml version="1.0"?>  2<!DOCTYPE module PUBLIC &n...  閱讀全文

    posted @ 2012-05-24 17:50 japper 閱讀(10082) | 評(píng)論 (0)編輯 收藏

    Myeclips打開(kāi)大數(shù)據(jù)量頁(yè)面時(shí)出現(xiàn)頁(yè)面錯(cuò)誤的解決辦法

    以前能夠正常運(yùn)行的程序今天突然出現(xiàn)頁(yè)面錯(cuò)誤,錯(cuò)誤日志大概如下:
    Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
        at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:
    82)
        at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:
    280)
         
    143 more
    Caused by: org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting 
    for idle object
        at org.apache.tomcat.dbcp.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:
    104)
        at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:
    880)
        at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:
    113)
        at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:
    79)
         
    144 more
    Caused by: java.util.NoSuchElementException: Timeout waiting 
    for idle object
        at org.apache.tomcat.dbcp.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:
    958)
        at org.apache.tomcat.dbcp.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:
    96)
         
    147 more
    2012-05-24 09:51:22,359 ERROR com.huawei.wsop.core.ExceptionAdvice - com.huawei.wsop.account.model.CustomerInfo@760c9f 執(zhí)行 getCustomer 時(shí)有異常拋出.org.springframework.jdbc.UncategorizedSQLException: Hibernate operation: Cannot open connection; uncategorized SQLException for SQL [???]; SQL state [null]; error code [0]; Cannot get a connection, pool error Timeout waiting for idle object; nested exception is org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:
    83)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:
    80)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:
    80)
    at org.springframework.orm.hibernate3.HibernateAccessor.convertJdbcAccessException(HibernateAccessor.java:
    424)
    at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:
    410)
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:
    424)
    at org.springframework.orm.hibernate3.HibernateTemplate.executeFind(HibernateTemplate.java:
    343)
    at com.huawei.wsop.account.dao.daoImpl.CustomerDaoImpl.getCustomer(CustomerDaoImpl.java:
    80)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
    39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
    25)
    at java.lang.reflect.Method.invoke(Method.java:
    597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:
    307)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:
    182)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
    149)
    at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:
    126)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
    171)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:
    89)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
    171)


    該頁(yè)面共有5W多條數(shù)據(jù),通過(guò)如下方法解決了: 
    在Eclipse中選擇
    window->preferences->myeclipse->servers->tomcat->jdk
    里面有個(gè)Optional java vm arguments
    在這里設(shè)置
    -Xms64m -Xmx500m
    xms標(biāo)識(shí)最小內(nèi)存  xmx標(biāo)識(shí)最大,根據(jù)你服務(wù)器的情況自行設(shè)置即可.

    posted @ 2012-05-24 10:36 japper 閱讀(1386) | 評(píng)論 (0)編輯 收藏

    主站蜘蛛池模板: 日韩亚洲综合精品国产| 免费av片在线观看网站| 青青草原精品国产亚洲av| 全部免费毛片在线| 蜜桃视频在线观看免费网址入口 | 性生交片免费无码看人| 少妇性饥渴无码A区免费| 国产精品亚洲天堂| 亚洲中文字幕一二三四区| 色播亚洲视频在线观看| 亚洲综合色自拍一区| 又爽又黄无遮挡高清免费视频 | 亚洲福利在线观看| 浮力影院亚洲国产第一页| 国产精品无码素人福利免费| 黄瓜视频影院在线观看免费| 一区二区三区观看免费中文视频在线播放| www永久免费视频| 大桥未久亚洲无av码在线| 亚洲国产精品无码久久九九大片| 亚洲乱人伦精品图片| 久久亚洲精品中文字幕| 亚洲AV永久纯肉无码精品动漫 | 国产三级在线免费| XXX2高清在线观看免费视频| 日日摸夜夜添夜夜免费视频| 国产午夜亚洲精品不卡电影| 色窝窝亚洲av网| 国产99久久亚洲综合精品| 毛片亚洲AV无码精品国产午夜| 亚洲爆乳大丰满无码专区| 亚洲成av人片在www鸭子| 久久精品国产亚洲AV电影网| 亚洲精品国产综合久久久久紧| 亚洲av第一网站久章草| 亚洲gay片在线gv网站| 老子影院午夜伦不卡亚洲| 极品色天使在线婷婷天堂亚洲| 青青草国产免费国产是公开| 免费手机在线看片| 国产精品免费久久久久电影网|