(如果您看到本文章務必看結尾!)
第一次用Timer類,記錄一下個人理解。
場景:做蘋果內容結果驗證時,根據蘋果支付憑證去蘋果官方服務器驗證是否支付成功。但因為蘋果服務器比較慢,第一次驗證的結果也許不是實時結果,需要多次驗證。
所以就使用到了Timer類,定時限制次數去驗證支付結果。
我設計的是每秒驗證一次,共驗證十次。
其實就Timer來講就是一個調度器,而TimerTask呢只是一個實現了run方法的一個類,而具體的TimerTask需要由你自己來實現,例如這樣:
Timer timer = new Timer(); timer.schedule(new TimerTask() { public void run() { System.out.println("每秒執行一次"); } }, 500 , 1000);
方法摘要:
void cancel() 終止此計時器,丟棄所有當前已安排的任務。
int purge() 從此計時器的任務隊列中移除所有已取消的任務。
void schedule(TimerTask task, Date time) 安排在指定的時間執行指定的任務。
void schedule(TimerTask task, Date firstTime, long period) 安排指定的任務在指定的時間開始進行重復的固定延遲執行。
void schedule(TimerTask task, long delay) 安排在指定延遲后執行指定的任務。
void schedule(TimerTask task, long delay, long period) 安排指定的任務從指定的延遲后開始進行重復的固定延遲執行。
void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) 安排指定的任務在指定的時間開始進行重復的固定速率執行。
void scheduleAtFixedRate(TimerTask task, long delay, long period) 安排指定的任務在指定的延遲后開始進行重復的固定速率執行。
知識點:線程中的變量參數用專門的變量類,如: ConcurrentMap<String, Integer> map
Test類:
1 package com.xxxx.controller; 2 3 import java.io.BufferedOutputStream; 4 import java.io.BufferedReader; 5 import java.io.InputStreamReader; 6 import java.net.URL; 7 import java.security.cert.CertificateException; 8 import java.security.cert.X509Certificate; 9 import java.util.Timer; 10 import java.util.TimerTask; 11 import java.util.concurrent.ConcurrentHashMap; 12 import java.util.concurrent.ConcurrentMap; 13 14 import javax.net.ssl.HttpsURLConnection; 15 import javax.net.ssl.SSLContext; 16 import javax.net.ssl.TrustManager; 17 import javax.net.ssl.X509TrustManager; 18 19 import com.alibaba.fastjson.JSONObject; 20 import com.wfcm.utils.R; 21 22 public class Test { 23 24 private static ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); 25 26 private static final String certificateUrlTest = "https://sandbox.itunes.apple.com/verifyReceipt"; 27 28 public static void main(String[] args) { 29 30 System.out.println(tim().toString()); 31 32 } 33 34 private static R tim () { 35 final Timer timer = new Timer(); 36 final String certificateCode1 = "234234234234"; 37 timer.schedule(new TimerTask() { 38 39 @Override 40 public void run() { 41 if (map.get(certificateCode1) != null) { 42 map.put(certificateCode1, map.get(certificateCode1) + 1); 43 } else { 44 map.put(certificateCode1, 1); 45 } 46 if (map.get(certificateCode1) >= 20) { 47 map.remove(certificateCode1); 48 timer.cancel(); 49 } 50 String r1 = sendHttpsCoon(certificateUrlTest, certificateCode1); 51 if (JSONObject.parseObject(r1).getString("status").equals("0")) { 52 map.remove(certificateCode1); 53 timer.cancel(); 54 } 55 System.out.println("設定指定任務task在指定延遲delay后執行"); 56 } 57 },500 , 1000); 58 System.out.println("******************方法結束"); 59 return R.error("68"); 60 } 61 62 private static String sendHttpsCoon(String url, String code){ 63 if(url.isEmpty()){ 64 return null; 65 } 66 try { 67 //設置SSLContext 68 SSLContext ssl = SSLContext.getInstance("SSL"); 69 ssl.init(null, new TrustManager[]{myX509TrustManager}, null); 70 71 //打開連接 72 HttpsURLConnection conn = (HttpsURLConnection) new URL(url).openConnection(); 73 //設置套接工廠 74 conn.setSSLSocketFactory(ssl.getSocketFactory()); 75 //加入數據 76 conn.setRequestMethod("POST"); 77 conn.setDoOutput(true); 78 conn.setRequestProperty("Content-type","application/json"); 79 80 JSONObject obj = new JSONObject(); 81 obj.put("receipt-data", code); 82 83 BufferedOutputStream buffOutStr = new BufferedOutputStream(conn.getOutputStream()); 84 buffOutStr.write(obj.toString().getBytes()); 85 buffOutStr.flush(); 86 buffOutStr.close(); 87 88 //獲取輸入流 89 BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); 90 91 String line = null; 92 StringBuffer sb = new StringBuffer(); 93 while((line = reader.readLine())!= null){ 94 sb.append(line); 95 } 96 return sb.toString(); 97 98 } catch (Exception e) { 99 return null; 100 } 101 } 102 103 private static TrustManager myX509TrustManager = new X509TrustManager() { 104 105 @Override 106 public X509Certificate[] getAcceptedIssuers() { 107 return null; 108 } 109 110 @Override 111 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 112 113 } 114 115 @Override 116 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 117 118 } 119 }; 120 } 121
第二次修訂:
在后續的學習中發現了一個更好的方法,同時也發現了Timer的不足之處。更多請看下面文章,寫的很好:
Timer的缺陷分析
.綜上所述,推薦使用ScheduleExecutorService ,在以后的開發中盡可能使用ScheduledExecutorService(JDK1.5以后)替代Timer。
或者使用Quartz,據說它也改善了這兩大缺陷
