<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年6月7日 #

    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 閱讀(6350) | 評(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 閱讀(346) | 評(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è)字母要大寫)
    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) | 評(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)類,分別是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í)寫HashMap;可能會(huì)導(dǎo)致數(shù)據(jù)的不一致。如果需要同步,可以用
    Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。


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


    LinkedHashMap
    是HashMap的一個(gè)子類,保存了記錄的插入順序,在用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í)寫HashMap,可能會(huì)導(dǎo)致數(shù)據(jù)的不一致性。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力。


    Hashtable與HashMap類似,不同的是:它不允許記錄的鍵或者值為空;它支持線程的同步,即任一時(shí)刻只有一個(gè)線程能寫Hashtable,因此也導(dǎo)致了Hashtable在寫入時(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 閱讀(16467) | 評(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ì)類成員變量的訪問(wèn):每個(gè)類實(shí)例對(duì)應(yīng)一把鎖,每個(gè) synchronized 方法都必須獲得調(diào)用該方法的類實(shí)例的鎖方能

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

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

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

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

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

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

    以通過(guò)將訪問(wè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 (如前所述,可以是類實(shí)例或類)的鎖方能執(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è)大房子,大門永遠(yuǎn)打開(kāi)。房子里有 很多房間(也就是方法)。

    這些房間有上鎖的(synchronized方法), 和不上鎖之分(普通方法)。房門口放著一把鑰匙(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)到房子門口,看見(jiàn)鑰匙在那兒(說(shuō)明暫時(shí)還沒(méi)有其他人要使用上鎖的 房間)。于是他走上去拿到了鑰匙

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

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

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

    這時(shí)其他人可以不受限制的使用那些不上鎖的房間,一個(gè)人用一間可以,兩個(gè)人用一間也可以,沒(méi)限制。但是如果當(dāng)某個(gè)人想要進(jì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)用一定的方法寫出來(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),而房門口卻還有

    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è)門呢?我想這純粹是因?yàn)閺?fù)雜性問(wèn)題。一個(gè)鑰匙一個(gè)門當(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ì)的分類,

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

    在進(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)銷作為代價(jià)的,甚至可能造成死鎖,所以盡量避免無(wú)謂的同步控制。

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

    假設(shè)P1、P2是同一個(gè)類的不同對(duì)象,這個(gè)類中定義了以下幾種情況的同步塊或同步方法,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í),就可以這樣寫程序,但當(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(類名稱字面常量)

        }   
    }

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

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

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

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

    可以推斷:如果一個(gè)類中定義了一個(gè)synchronized的static函數(shù)A,也定義了一個(gè)synchronized 的instance函數(shù)B,那么這個(gè)類的同一對(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”畫面中,選擇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. 配置完成了,三個(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ù)管理工具,類似于 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、去掉拼寫檢查(如果你覺(jué)的有用可以不去)

    拼寫檢查會(huì)給我們帶來(lái)不少的麻煩,我們的方法命名都會(huì)是單詞的縮寫,他也會(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] 寫代碼很容易卡死機(jī),尤其是在對(duì)JSP文件的﹤%%﹥之間寫代碼的時(shí)候,只要一彈出智能提示就立刻卡死,程序失去響應(yīng),我以為是MyEclipse版本的問(wèn)題,結(jié)果換了6.0版-﹥6.5版-﹥7.0版全都一樣,難道是我機(jī)子的問(wèn)題?可是還原系統(tǒng)后用還是一樣的結(jié)果。

    百度一下你就知道,但是百度了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寫代碼,結(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 閱讀(1010) | 評(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>
    類似的還有:
    $(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ù)的類型 (html,xml,json,jasonp,script,text)

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

    略。。。


















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

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

    1、通過(guò)jx1最新版本的采用臨時(shí)文件寫入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、在寫入EXCEL的時(shí)候,將讀取的LIST分割,每50000條數(shù)據(jù)生成一個(gè)EXCEL的sheet(一個(gè)sheet最多能存儲(chǔ)60000多行數(shù)據(jù)),再寫入,寫入的時(shí)候,如果設(shè)置了采用臨時(shí)文件寫入的話,jx1會(huì)自動(dòng)采用生成臨時(shí)文件的方式寫入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盤符空間不足的解決辦法

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

    如果臨時(shí)表空間或者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)的臨時(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)。直到耗盡硬盤空間。
    網(wǎng)上有人猜測(cè)在磁盤空間的分配上,oracle使用的是貪心算法,如果上次磁盤空間消耗達(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類型的數(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">蘋果<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">蘋果<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來(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)編輯 收藏

    主站蜘蛛池模板: 夜夜嘿视频免费看| 浮力影院第一页小视频国产在线观看免费 | 亚洲av乱码一区二区三区按摩 | 久久亚洲欧美国产精品| 69成人免费视频无码专区| 在线亚洲高清揄拍自拍一品区| 国产1024精品视频专区免费| 亚洲av永久综合在线观看尤物| 91精品免费国产高清在线| 亚洲人成片在线观看| 成人免费午夜无码视频| 亚洲av乱码一区二区三区香蕉| 久久精品免费全国观看国产| 国产午夜亚洲精品| 日韩视频免费一区二区三区| 亚洲av无码成人精品国产| 四虎永久免费影院| 一级做a爰黑人又硬又粗免费看51社区国产精品视 | 亚洲国产区男人本色| 免费精品一区二区三区在线观看| 亚洲乱妇老熟女爽到高潮的片| 免费日本一区二区| 久久久久亚洲精品成人网小说| 亚洲电影免费在线观看| 亚洲欧洲日产韩国在线| 国产成人免费网站| 久久精品国产亚洲AV未满十八| 免费a级毛片大学生免费观看| 特级做a爰片毛片免费看| 亚洲AV中文无码字幕色三| 8090在线观看免费观看| tom影院亚洲国产一区二区| 免费羞羞视频网站| 人人爽人人爽人人片av免费| 亚洲精品午夜无码电影网| 免费国产黄网站在线观看视频| 亚洲中文无码av永久| 日韩高清在线高清免费| 一级特黄a大片免费| 亚洲av永久无码精品古装片| 成人免费大片免费观看网站|