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

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

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

    ……天天向上

    好的想法總是無窮無盡

    統(tǒng)計(jì)

    留言簿(1)

    閱讀排行榜

    評論排行榜

    2012年6月5日 #

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

    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 閱讀(6350) | 評論 (0)編輯 收藏

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


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

     

    最近剛換了電腦,開始搭建Android開發(fā)環(huán)境的時候,下載SDK總是會出現(xiàn)如下錯誤:
     
    1.Failed to fetch URL http://dl-ssl.google.com/Android/repository/addons_list-1.xml
    據(jù)說dl-ssl.google.com在大陸被強(qiáng)了,偉大的天朝真是不讓人活了,解決方法就是修改C:\Windows\System32\drivers\etc\hosts文件。添加一行:
     
    1.74.125.237.1       dl-ssl.google.com 
    這里需要注意的是hosts文件是只讀的,我們沒有權(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 目錄,替換文件就好!!!我們再次下載SDK的時候就會成功啦,如下圖:
     


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

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

    免安裝版Tomcat 6.0.35碰到的問題 :打開tomcat管理界面時,用戶名和密碼錯誤的設(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 這個地方的密碼是在安裝的時候指定的,但是呢,Tomcat 6.0.35 由于是免安裝的,所以就沒有地方去指定密碼了,當(dāng)我們訪問Tomcat 6.0.35 的Tomcat Manager的時候 ,輸入以前默認(rèn)的用戶名:admin 密碼為空,會發(fā)現(xiàn)出現(xiàn)了403 錯誤,即access deny 。調(diào)試了好久,最后終于找出原因了。根據(jù)403頁面的提示,需要在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) | 評論 (0)編輯 收藏

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

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

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

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

    第一步、配置tomcat

    打開%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 

    在每個“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)程連接會因?yàn)榻馕龅?/font>127.0.0.1失敗,該項(xiàng)的值就是你在windows客戶端連接linux時的ip地址

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

    sslauthenticate設(shè)置為false,如果需要安全,請不要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ù),如果無效使用kill命令殺掉進(jìn)程

    [root@test ~]#./startup.sh  --啟動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è)置的端口號:9004

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

    posted @ 2012-09-05 14:16 japper 閱讀(3957) | 評論 (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. //端口最好是動態(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ù)對應(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("啟動時間:" + df.format(starttime));
    65. Long timespan = (Long) mbsc.getAttribute(runtimeObjName, "Uptime");
    66. System.out.println("連續(xù)工作時間:" + 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("最大會話數(shù):" + mbsc.getAttribute(objname, "maxActiveSessions"));
    93. System.out.println("會話數(shù):" + mbsc.getAttribute(objname, "activeSessions"));
    94. System.out.println("活動會話數(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都打印出來
    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. // 對name屬性的操作(屬性名的第一個字母要大寫)
    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 閱讀(4990) | 評論 (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)去的對象位置未發(fā)生變化,而HashMap會發(fā)生變化.


    再普及下:




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


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


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


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


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


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


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


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


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


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


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

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

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

    記下來,很重要。

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

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

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

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

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

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

    舉例說明: 
         一、當(dāng)兩個并發(fā)線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內(nèi)只能有一個線程得到執(zhí)行。另一個線程必須等待當(dāng)前線程執(zhí)行完這個代碼塊以后才能執(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)一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該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)一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。

         //修改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

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

         //修改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ī)則對其它對象鎖同樣適用:

    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) { //使用對象鎖    
              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獲得了對Inner的對象鎖,但由于線程t2訪問的是同一個Inner中的非同步部分。所以兩個線程互不干擾。

         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訪問了同一個Inner對象中兩個毫不相關(guān)的部分,但因?yàn)閠1先獲得了對Inner的對象鎖,所以t2對Inner.m4t2()的訪問也被阻塞,因?yàn)閙4t2()是Inner中的一個同步方法。

         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 方法:通過在方法聲明中加入 synchronized關(guān)鍵字來聲明 synchronized 方法。如: 
    public synchronized void accessVal(int newVal); 
    synchronized 方法控制對類成員變量的訪問:每個類實(shí)例對應(yīng)一把鎖,每個 synchronized 方法都必須獲得調(diào)用該方法的類實(shí)例的鎖方能

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    一個人想進(jìn)入某間上了鎖的房間,他來到房子門口,看見鑰匙在那兒(說明暫時還沒有其他人要使用上鎖的 房間)。于是他走上去拿到了鑰匙

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

    中間他也要把鑰匙還回去,再取回來。

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

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

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

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

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

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

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

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

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

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

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

    再來看看同步代碼塊。和同步方法有小小的不同。

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

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

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

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

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

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

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

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

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

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

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

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

    1000個線程在等這把鑰匙呢。很過癮吧。

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

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

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

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

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

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

    synchronized的一個簡單例子

    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--);    
        }    
       }    
    }    
    }

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

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

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

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

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

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

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

    他線程的對象訪問。

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

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

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

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

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

    Public synchronized void methodAAA()

    {

    //….

    }

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

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

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

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

    public void methodAAA()

    {

    synchronized (this)      // (1)

    {

           //…..

    }

    }

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

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

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

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

    public void method3(SomeObject so)

    {

        synchronized(so)

        {   
           //…..    
        }

    }

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

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

    class Foo implements Runnable

    {

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

            Public void methodA()   
            {

               synchronized(lock) { //… }

            }

            //…..

    }

    注:零長度的byte數(shù)組對象創(chuàng)建起來將比任何對象都經(jīng)濟(jì)――查看編譯后的字節(jié)碼:生成零長度的byte[]對象只需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(類名稱字面常量)

        }   
    }

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

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

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

    目的。P1指的是由Foo類產(chǎn)生的對象。

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

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

    小結(jié)如下:

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

    還有一些技巧可以讓我們對共享資源的同步訪問更加安全:

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

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

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

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

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

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

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

    MyEclipse的基礎(chǔ)配置:


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

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

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

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

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

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

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

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




     

     

    優(yōu)化MyEclipse:

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

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

    關(guān)掉沒用的啟動項(xiàng):

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

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

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

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

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

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


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

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

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

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

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

    如果是myeclipse7.5:

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

    window-preferences-MyEclipse Enterprise Workbench-Maven4MyEclipse-Maven,
    關(guān)閉所有Download和Update開頭的選項(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)存

    打開 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)在相同的條件下做過測試(內(nèi)存2GB),-Xmx,-XX:MaxPermSize的值為384m時比512m時要快(視具體的計(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)過以上的優(yōu)化,myeclipse的啟動時間可以減少2/3,Tomcat的啟動速度可以減少1/2(視具體情況而定),

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

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

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

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

    在自己創(chuàng)建的工程名上右鍵,選擇Properties--﹥在打開的窗口中點(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 閱讀(1010) | 評論 (0)編輯 收藏

    jquery筆記0717

    1、不常用的切換函數(shù)$("p").toggle();當(dāng)點(diǎn)擊切換按鈕時,隱藏元素為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">請點(diǎn)擊這里</button>
    </body>

    </html>
    類似的還有:
    $(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}) 同時為所有匹配元素的一系列 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è)置多個樣式屬性
    $(selector).css(name) 獲得第一個匹配元素的樣式屬性值
    $(selector).height(value) 設(shè)置匹配元素的高度
    $(selector).width(value) 設(shè)置匹配元素的寬度

    4、AJAX:

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

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

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

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

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

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

    略。。。


















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

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

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


    2、EXCEL獲取的list集合先讀取數(shù)據(jù)總行數(shù),再通過ROWNUM進(jìn)行控制,設(shè)定每次讀取多少行數(shù)據(jù),比如一個List設(shè)定為50000;
                WorkbookSettings wbSetting = new WorkbookSettings();   
                wbSetting.setUseTemporaryFileDuringWrite(true);   
                wbSetting.setTemporaryFileDuringWriteDirectory(new File(excelPath));//臨時文件夾的位置
                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()); // 總頁數(shù)
                    for (int i = 1; i 
    <= pager.getTotalPages(); i++) {
                        pager.setCurrentPage(i); // 當(dāng)前頁面d
                        List<BrasAuth
    > list = BrasDatabase
                                .getBrasAuthResultByIpToExcelList(pager
                                        .getStartTime(), pager.getEndTime(), pager);
                        this.createExcel(list,excelFilePath);
                        list.clear();
                    }
                }



    3、在寫入EXCEL的時候,將讀取的LIST分割,每50000條數(shù)據(jù)生成一個EXCEL的sheet(一個sheet最多能存儲60000多行數(shù)據(jù)),再寫入,寫入的時候,如果設(shè)置了采用臨時文件寫入的話,jx1會自動采用生成臨時文件的方式寫入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) | 評論 (1)編輯 收藏

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

    由于開發(fā)經(jīng)驗(yàn)較少,數(shù)據(jù)量較大(千萬級,日有40萬條數(shù)據(jù)左右),導(dǎo)致這個分頁jsp頁面做的效率非常低,通過一系列的優(yōu)化后,效果明顯得到了提高,記錄一下筆記:
    1、分頁獲取的list對象集合由于沒有預(yù)料到數(shù)據(jù)量的大小,是直接一次性讀取然后展示到前臺的,導(dǎo)致查詢展示效率非常低:
    更改SQL語句,改為按照當(dāng)前需要展示的數(shù)據(jù)行數(shù),通過SQL的ROWNUM來進(jìn)行控制查詢的數(shù)據(jù)量大小,(插入數(shù)據(jù)時,打開一個數(shù)據(jù)庫連接即一次性插入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ù)放在一個表中:


    ----------------------刪除原表,新建分區(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'))
    )
    --保留原來創(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) | 評論 (0)編輯 收藏

    ORACLE復(fù)制千萬級數(shù)據(jù)表時用的存儲過程

    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 查詢語句
                                              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語句
      e_sql   varchar2(10000);--執(zhí)行SQL語句
      countNumber number;--一次插入的數(shù)據(jù)量
    begin
      --set serveroutput on size 20000000000000
      countNumber := 10000;
      return_result := 0; --開始初始化為0
      --核必邏輯內(nèi)容,可根據(jù)具體的業(yè)務(wù)邏輯來定義,統(tǒng)計(jì)數(shù)據(jù)總行數(shù)
      s_sql := 'select count(1) from (' || ip_table_select || ')';
      execute immediate s_sql
        into amount;
      --每100萬提交一次
      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;



    以上測試通過。

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

    ORACLE所在linux盤符空間不足的解決辦法

    ORACLE數(shù)據(jù)庫空間不足,會發(fā)生登錄出錯,數(shù)據(jù)無法插入等錯誤發(fā)生,可以根據(jù)實(shí)際錯誤代碼查詢原因,不過更多是平時多看看數(shù)據(jù)庫空間是否足夠;
    解決辦法有兩個:
    1、使用linux命令或者工具增加空間或者增加硬盤,沒有實(shí)際操作過;
    2、給oracel數(shù)據(jù)庫增加系統(tǒng)表空間和臨時表空間,記錄下操作方法:

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

    如果startup數(shù)據(jù)庫時,提示:prifile文件找不到,可以從一個$ORACLE_BASE/admin/portal/pfile目錄下拷貝內(nè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) | 評論 (0)編輯 收藏

    oracle 臨時表空間的增刪改查

    oracle 臨時表空間的增刪改查

    1、查看臨時表空間 (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、縮小臨時表空間大小
    alter database tempfile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\TELEMT\TEMP01.DBF' resize 100M;

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

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

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

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

    7、查看臨時表空間的使用情況(GV_$TEMP_SPACE_HEADER視圖必須在sys用戶下才能查詢)
    GV_$TEMP_SPACE_HEADER視圖記錄了臨時表空間的使用大小與未使用的大小
    dba_temp_files視圖的bytes字段記錄的是臨時表空間的總大小
    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語句
    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)前臨時表空間使用大小與正在占用臨時表空間的sql語句
    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、臨時表空間組介紹
      1)創(chuàng)建臨時表空間組:
    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)查詢臨時表空間組:dba_tablespace_groups視圖
    select * from dba_tablespace_groups;
    GROUP_NAME                     TABLESPACE_NAME
    ------------------------------ ------------------------------
    GROUP1                         TEMPTS1
    GROUP2                         TEMPTS2

     3)將表空間從一個臨時表空間組移動到另外一個臨時表空間組:
    alter tablespace tempts1 tablespace group GROUP2 ;
    select * from dba_tablespace_groups;

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

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

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

     6)刪除臨時表空間組 (刪除組成臨時表空間組的所有臨時表空間)
    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、對臨時表空間進(jìn)行shrink(11g新增的功能)
    --將temp表空間收縮為20M
    alter tablespace temp shrink space keep 20M;
    --自動將表空間的臨時文件縮小到最小可能的大小
    ALTER TABLESPACE temp SHRINK TEMPFILE ’/u02/oracle/data/lmtemp02.dbf’;

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

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

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

    在JQuery中使用jsp頁面的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();//獲取本頁面其他標(biāo)簽的值 
    window.location.href="xx.php?param1="+p1+"¶m2="+p2+"";//頁面跳轉(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ù)加載動態(tài)顯示:即將DIV顯示出來
            $("#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" >每頁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">每頁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">每頁30行</option>
                  <option selected="selected" value="">---請選擇---</option>
                  </select>

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

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

    初學(xué)的知識,怕忘記了,記錄下:
        /**
         *  測試SELECT COUNT(*)返回int類型的數(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"); //通過指定別名返回行數(shù)
                    number1=rs.getInt(1); //通過索引返回行數(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) | 評論 (0)編輯 收藏

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

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

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

    <form action="

    請輸入你的姓名:

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

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

    </form>

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

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

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

    至于method,表示了發(fā)送表單信息的方式。method有兩個值:get和post。get的方式是將表單控件的name/value信息經(jīng)過編碼之后,通過URL發(fā)送(你可以在地址欄里看到)。而post則將表單的內(nèi)容通過http發(fā)送,你在地址欄看不到表單的提交信息。那什么時候用get,什么時候用post呢?一般是這樣來判斷的,如果只是為取得和顯示數(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):單行文本輸入框(input type="text")
    單行文本輸入框允許用戶輸入一些簡短的單行信息,比如用戶姓名
    。例句如下:

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

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

    <input type="checkbox" name="fruit" value ="apple">蘋果<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):單選框(input type="radio")
    使用單選框,讓用戶在一組選項(xiàng)里只能選擇一個。示例代碼:

    <input type="radio" name="fruit" value = "Apple">蘋果<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">蘋果

    <option value="orange">桔子

    <option value="mango">芒果

    </select>

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

    <select name="fruit" multiple>

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

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

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

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

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

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

    表單控件(Form Control):提交(input type="submit")
    通過提交(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 以一個圖片作為表單的提交按鈕,其中 src 屬性表示圖片的路徑。

    <input type="image" src ="

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

    GET和POST兩種提交表單的方式說明

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

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

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


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

    <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個字段,用戶名(username)和密碼(password)
    注意form標(biāo)簽中的method參數(shù)值是post!

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

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

    arg0=urlencode(value0)&arg1=urlencode(value1)
    當(dāng)然,尤其要注意字段名,參數(shù)名只不能使用中文這類字符。
    3、通過httpclient來模擬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);
                
    //這里需要生成并傳遞一個COOKIE過去
                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(
    "測試地址: " + 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) | 評論 (1)編輯 收藏

    表單提交的幾種方式

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

        4、阻止表單提交

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

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

    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 () {
        //取得事件對象
        event = EventUtil.getEvent(event);
        //阻止默認(rèn)事件
        EventUtil.preventDefault(event);
    });  
    調(diào)用preventDefault()方法阻止了表單提交。一般來說,在表單數(shù)據(jù)無效而不能發(fā)送給服務(wù)器時,可以使用這一技術(shù)。

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

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

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

     

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

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

    java.version

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

    java.vendor

    Java 運(yùn)行時環(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ī)范名稱

    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)名稱

    java.specification.version

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

    java.specification.vendor

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

    java.specification.name

    Java 運(yùn)行時環(huán)境規(guī)范名稱

    java.class.version

    Java 類格式版本號

    java.class.path

    Java 類路徑

    java.library.path

    加載庫時搜索的路徑列表

    java.io.tmpdir

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

    java.compiler

    要使用的 JIT 編譯器的名稱

    java.ext.dirs

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

    os.name

    操作系統(tǒ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

    用戶的賬戶名稱

    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) | 評論 (0)編輯 收藏

    主站蜘蛛池模板: 亚洲成av人片在线天堂无| 一区在线免费观看| 中文免费观看视频网站| 亚洲情综合五月天| 国产亚洲精品第一综合| 亚洲91精品麻豆国产系列在线| 一本色道久久综合亚洲精品蜜桃冫| 免费无码VA一区二区三区 | 国产亚洲精品免费| 午夜一级免费视频| 亚洲一欧洲中文字幕在线| 91香蕉国产线在线观看免费| 亚洲国产精品一区第二页| 国产精品美女免费视频观看| 亚洲A∨午夜成人片精品网站 | 91在线品视觉盛宴免费| 亚洲精品国产电影午夜| 亚洲视频免费在线观看| 亚洲不卡中文字幕无码| 久久精品成人免费网站| 亚洲国产精品久久久天堂| 中文字幕在线视频免费观看| 久久国产成人亚洲精品影院| gogo免费在线观看| 亚洲日韩在线观看免费视频| 亚洲一区二区三区久久| 在线看片韩国免费人成视频| 亚洲香蕉成人AV网站在线观看| 一区免费在线观看| www视频在线观看免费| 亚洲另类激情综合偷自拍图| 中文字幕不卡高清免费| 亚洲色婷婷六月亚洲婷婷6月| 99re6在线精品免费观看| 亚洲日韩精品一区二区三区| 免费人成在线观看视频高潮| 亚洲av无码乱码国产精品| 特级无码毛片免费视频尤物| 色拍自拍亚洲综合图区| 成人免费的性色视频| 亚洲日本va在线观看|