我们都知道单例模式,有很多种实现方法。今天我们实现一个单线程实例模式,也就是说只能实例化该类的一个线程来运行,不允许有该类的多个线程实例存在。直接上代码:
public class SingletonThread implements Runnable
{
? ? /** 获取access_token 和 expire_in 的url */
? ? private static final String accessTokenUrl =
"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? + ParameterConfig.WX_APPID + "&secret=" + ParameterConfig.WX_APPSECRET;
? ?
? ? /** 这里使用public volatile发布一个共享对象 */
? ? private static volatile AccessToken accessToken; // 因为是一个线程写多个线程读,而引用的又是“不可变对象”,
// 所以使用volatile保证“可见性”
? ?
? ? // 保证无法实例化 SingletonThread
? ? private SingletonThread(){}
? ?
? ? // 静态类保证thread的初始化是线程安全的,内部类实现了延迟加载的效果
? ? private static class SingletonThreadHolder
? ? {
? ? ? ? public static SingletonThread thread = new SingletonThread();
? ? }
? ?
? ? public static SingletonThread getInstance()
? ? {
? ? ? ? return SingletonThreadHolder.thread;
? ? }
? ?
? ? @Override
? ? public void run()
? ? {
? ? ? ? while(true)
? ? ? ? {
? ? ? ? ? ? try{
? ? ? ? ? ? ? ? HttpsURLConnection conn = HttpUtil.initHttpsConnection(accessTokenUrl, "GET");
? ? ? ? ? ? ? ? String result = HttpUtil.getHttpsContent(conn, "utf-8");
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? JSONObject json = null;
? ? ? ? ? ? ? ? if(result != null)
? ? ? ? ? ? ? ? ? ? json = JSON.parseObject(result);
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? if(json != null){
? ? ? ? ? ? ? ? ? ? accessToken? = new AccessToken(json.getString("access_token"), json.getLong("expires_in"));
? ? ? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? ? ? System.out.println("get access_token failed----");
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }catch(IOException e){
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? ? ?
? ? ? ? ? ? try{
? ? ? ? ? ? ? ? if(null != accessToken){
? ? ? ? ? ? ? ? ? ? Thread.sleep((accessToken.getExpire_in() - 200) * 1000);? ? // 休眠7000秒
? ? ? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? ? ? Thread.sleep(60 * 1000);? ? // 如果access_token为null,60秒后再获取
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }catch(InterruptedException e){
? ? ? ? ? ? ? ? try{
? ? ? ? ? ? ? ? ? ? Thread.sleep(60 * 1000);
? ? ? ? ? ? ? ? }catch(InterruptedException e1){
? ? ? ? ? ? ? ? ? ? e1.printStackTrace();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? public static AccessToken getAccessToken() {
? ? ? ? return accessToken;
? ? }? ?
}
也可以扩展Thread类来实现:
public class SingletonThread2 extends Thread
{
? ? /** 获取access_token 和 expire_in 的url */
? ? private static final String accessTokenUrl =
"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? + ParameterConfig.WX_APPID + "&secret=" + ParameterConfig.WX_APPSECRET;
? ?
? ? // 这里使用public发布一个共享对象
? ? private static volatile AccessToken accessToken; // 因为是一个线程写多个线程读,而引用的又是“不可变对象”,
// 所以使用volatile保证“可见性”
? ?
? ? // 保证无法实例化 SingletonThread
? ? private SingletonThread2(){}
? ?
? ? // 静态类保证thread的初始化是线程安全的,内部类实现了延迟加载的效果
? ? private static class SingletonThreadHolder
? ? {
? ? ? ? public static SingletonThread2 thread = new SingletonThread2();
? ? }
? ?
? ? public static SingletonThread2 getInstance()
? ? {
? ? ? ? return SingletonThreadHolder.thread;
? ? }
? ?
? ? @Override
? ? public void run()
? ? {
? ? ? ? while(true)
? ? ? ? {
? ? ? ? ? ? try{
? ? ? ? ? ? ? ? HttpsURLConnection conn = HttpUtil.initHttpsConnection(accessTokenUrl, "GET");
? ? ? ? ? ? ? ? String result = HttpUtil.getHttpsContent(conn, "utf-8");
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? JSONObject json = null;
? ? ? ? ? ? ? ? if(result != null)
? ? ? ? ? ? ? ? ? ? json = JSON.parseObject(result);
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? if(json != null){
? ? ? ? ? ? ? ? ? ? accessToken = new AccessToken(json.getString("access_token"), json.getLong("expires_in"));
? ? ? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? ? ? System.out.println("get access