Java優化
效率可以大幅度提升的空間在資料庫操作部分以及程式控制部分。下面,分條敘述對耗時操作的改進方法。
針對日誌記錄的優化
關閉日誌記錄,或者更改日誌輸出級別。因為從兩臺伺服器的外部系統 D 上獲取到的資訊是相同的,所以資料庫插入操作會丟擲異常,異常資訊類似於“Attempt to insert duplicate record”,這樣的異常資訊跟有效資訊的條數相等,有上千條。這種情況是能預料到的,所以可以考慮關閉日誌記錄,或者不關閉日誌記錄而是更改日誌輸出級別,只記錄嚴重級別(severe level)的錯誤資訊,並將此類操作的日誌級別調整為警告級別(warning level),這樣就不會記錄以上異常資訊了。本專案使用的是 Java 自帶的日誌記錄類,以下配置檔案將日誌輸出級別設定為嚴重級別。
清單 1. log.properties 設定日誌輸出級別的片段
# default file output is in user ’ s home directory. # levels can be: SEVERE, WARNING, INFO, FINE, FINER, FINEST java.util.logging.ConsoleHandler.level=SEVERE java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.FileHandler.append=true
針對資料庫連線的優化
共享資料庫連線。共有 5 次資料庫連線操作,每次都需重新建立資料庫連線,資料庫插入操作完成之後又立即釋放了,資料庫連線沒有被複用。為了做到共享資料庫連線,可以通過單例模式(Singleton Pattern)獲得一個相同的資料庫連線,每次資料庫連線操作都共享這個資料庫連線。這裡沒有使用資料庫連線池(Database Connection Pool)是因為在程式只有少量的資料庫連線操作,只有在大量併發資料庫連線的時候才需要連線池。
清單 2. 共享資料庫連線的程式碼片段
public class JdbcUtil { private static Connection con; // 從配置檔案讀取連線資料庫的資訊 private static String driverClassName; private static String url; private static String username; private static String password; private static String currentSchema; private static Properties properties = new Properties(); static { // driverClassName, url, username, password, currentSchema 等從配置檔案讀取,程式碼略去 try { Class.forName(driverClassName); } catch (ClassNotFoundException e) { e.printStackTrace(); } properties.setProperty("user", username); properties.setProperty("password", password); properties.setProperty("currentSchema", currentSchema); try { con = DriverManager.getConnection(url, properties); } catch (SQLException e) { e.printStackTrace(); } } private JdbcUtil() {} // 獲得一個單例的、共享的資料庫連線 public static Connection getConnection() { return con; } public static void close() throws SQLException { if (con != null) con.close(); } }
針對插入資料庫記錄的優化 1
使用預編譯 SQL。具體做法是使用 java.sql.PreparedStatement 代替 java.sql.Statement 生成 SQL 語句。PreparedStatement 使得資料庫預先編譯好 SQL 語句,可以傳入引數。
清單 3. 使用 Statement 的程式碼片段
// 需要拼接 SQL 語句,執行效率不高,程式碼可讀性不強 StringBuilder sql = new StringBuilder(); sql.append("insert into table1(column1,column2) values('"); sql.append(column1Value); sql.append("','"); sql.append(column2Value); sql.append("');"); Statement st; try { st = con.createStatement(); st.executeUpdate(sql.toString()); } catch (SQLException e) { e.printStackTrace(); }
清單 4. 使用 PreparedStatement 的程式碼片段
// 預編譯 SQL 語句,執行效率高,可讀性強 String sql = “insert into table1(column1,column2) values(?,?)”; PreparedStatement pst = con.prepareStatement(sql); pst.setString(1,column1Value); pst.setString(2,column2Value); pst.execute();
針對插入資料庫記錄的優化 2
使用 SQL 批處理。
針對多執行緒的優化
使用多執行緒實現併發 / 並行。
清空資料庫表的操作應該先於資料庫插入操作完成,可以通過 java.lang.Thread 類的 join 方法控制執行緒執行的先後次序。在單核 CPU 時代,作業系統中某一時刻只有一個執行緒在執行,通過程式 / 執行緒排程,給每個執行緒分配一小段執行的時間片,可以實現多個程式 / 執行緒的併發(concurrent)執行。而在目前的多核多處理器背景下,作業系統中同一時刻可以有多個執行緒並行(parallel)執行,大大地提高了計算速度。
清單 5. 使用多執行緒的程式碼片段
Thread t0 = new Thread(new ClearTableTask()); Thread t1 = new Thread(new StoreServersTask(ADDRESS1)); Thread t2 = new Thread(new StoreServersTask(ADDRESS2)); try { t0.start(); // 執行完清空操作後,再進行後續操作 t0.join(); t1.start(); t2.start(); t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } // 斷開資料庫連線 try { JdbcUtil.close(); } catch (SQLException e) { e.printStackTrace(); }
針對設計模式的優化
使用 DAO 模式抽象出資料訪問層。
圖 2. DAO 模式的層次結構
清單 6. 使用 DAO 模式的程式碼片段
// DeviceDAO.java,定義了 DAO 抽象,上層的業務邏輯程式碼引用該介面,面向介面程式設計 public interface DeviceDAO { public void add(Device device); } // DeviceDAOImpl.java,DAO 實現,具體的 SQL 語句和資料庫操作由該類實現 public class DeviceDAOImpl implements DeviceDAO { private Connection con; public DeviceDAOImpl() { // 獲得資料庫連線,程式碼略去 } @Override public void add(Device device) { // 使用 PreparedStatement 進行資料庫插入記錄操作,程式碼略去 } }
結束語
通過該專案例項,筆者深深地感到,想要寫出一個效能優化、可讀性可擴充套件性強的程式,需要對計算機系統的基本概念、原理,程式語言的特性,軟體系統架構設計都有較深入的理解。“紙上得來終覺淺,絕知此事要躬行”,想要將這些基本理論、程式設計技巧融會貫通,還需要不斷地實踐,並總結心得體會。
連結:http://www.ibm.com/developerworks/cn/java/j-lo-codeoptimize/
相關文章
- java效能優化Java優化
- java Synchronized的優化Javasynchronized優化
- Java程式碼優化Java優化
- JAVA效能優化思路探究Java優化
- 【Java效能優化思路方向】Java優化
- Java反射與反射優化Java反射優化
- Java效能優化技巧集合Java優化
- [java][效能優化]java高階開發必會的50個效能優化Java優化
- 《java學習三》jvm效能優化-------調優JavaJVM優化
- 怎麼做好Java效能優化Java優化
- [java][鎖]java鎖的膨脹和優化Java優化
- Java 條件表示式的優化Java優化
- Java學習之程式碼優化Java優化
- Java 後臺效能優化簡要Java優化
- Java效能優化的5個技巧Java優化
- java效能優化方案——使用entrySet()Java優化
- Java後臺效能優化簡要Java優化
- java優化程式設計-物件重用Java優化程式設計物件
- 多核平臺下的JAVA優化Java優化
- Java 效能優化技巧及實戰Java優化
- Java程式碼優化(長期更新)Java優化
- java效能優化方案9——優化自定義hasCode()方法和equals()方法Java優化
- 深入理解JVM(③)Java的鎖優化JVMJava優化
- java多型-優化上個例項Java多型優化
- jvm系列(十):如何優化Java GC「譯」JVM優化JavaGC
- 推薦:Java效能優化系列集錦Java優化
- 【推薦】Java效能優化系列集錦Java優化
- 10種簡單的Java效能優化Java優化
- Java Web 前端高效能優化(二)JavaWeb前端優化
- Java I/O 操作及優化建議Java優化
- Java 效能優化之——效能優化的過程方法與求職面經總結Java優化求職
- 前端效能優化(JS/CSS優化,SEO優化)前端優化JSCSS
- Java 執行緒與同步的效能優化Java執行緒優化
- 《java學習三》jvm效能優化------jconsulJavaJVM優化
- Java高併發實戰,鎖的優化Java優化
- Effective Java -- 使用try-with-resources優化程式碼Java優化
- java程式碼編寫優化(持續更新...)Java優化
- MemCached Cache Java Client封裝優化歷程Javaclient封裝優化