java实现单线程_使用Java实现单线程模式

咱们都知道单例模式,有不少种实现方法。今天咱们实现一个单线程实例模式,也就是说只能实例化该类的一个线程来运行,不容许有该类的多个线程实例存在。直接上代码:java

public class SingletonThread implementsRunnable

{/**获取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

privateSingletonThread(){}//静态类保证thread的初始化是线程安全的,内部类实现了延迟加载的效果

private static classSingletonThreadHolder

{public static SingletonThread thread = newSingletonThread();

}public staticSingletonThread getInstance()

{returnSingletonThreadHolder.thread;

}

@Overridepublic voidrun()

{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类来实现:json

public class SingletonThread2 extendsThread

{/**获取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发布一个共享对象

privatestatic volatile AccessToken accessToken; //由于是一个线程写多个线程读,而引用的又是“不可变对象”,

// 因此使用volatile保证“可见性”//保证没法实例化 SingletonThread

privateSingletonThread2(){}//静态类保证thread的初始化是线程安全的,内部类实现了延迟加载的效果

private static classSingletonThreadHolder

{public static SingletonThread2 thread = newSingletonThread2();

}public staticSingletonThread2 getInstance()

{returnSingletonThreadHolder.thread;

}

@Overridepublic voidrun()

{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;

}

}

这里的场景是:微信开发中须要每隔2个小时从腾讯的微信服务器刷新access_token,因此这里只须要使用单个线程无线循环每隔2小时刷新一次便可,咱们不但愿出现该类的多个线程,每一个线程都去刷新access_token。api

注意若是在一个线程上调用屡次 start() 方法是会抛出 IllegalThreadStateException 异常的。安全

这里的实现其实也来自于单实例模式的一种写法,实现了线程安全和延迟加载的效果。其实对应于单例模式,单线程模式也有多种实现方法,好比使用 静态属性:服务器

public class SingletonThread3 extends Thread

{

private static SingletonThread3 thread = new SingletonThread3(); // static保证线程安全

// 保证没法实例化 SingletonThread

private SingletonThread3(){}

public static SingletonThread3 getInstance()

{

return thread;

}

@Override

public void run()

{

// ...

}

}

这种实现也是线程安全的,可是没有延迟加载的效果。微信

AccessToken是一个“不可变对象”的类:微信开发

/*** access_token是公众号的全局惟一票据,公众号调用各接口时都需使用access_token。

* 开发者须要进行妥善保存。access_token的存储至少要保留512个字符空间。

* access_token的有效期目前为2个小时,需定时刷新,重复获取将致使上次获取的access_token失效。

* 目前access_token的有效期经过返回的expire_in来传达,目前是7200秒以内的值

*@authordigdeep@126.com

* 这是一个“不可变”对象的类定义*/

public classAccessToken

{private finalString access_token;private final long expire_in; //access_token有效时间,单位为妙

public AccessToken(String access_token, longexpire_in)

{this.access_token =access_token;this.expire_in =expire_in;

}publicString getAccess_token() {returnaccess_token;

}public longgetExpire_in() {returnexpire_in;

}

}

其实几乎能够将每一种单实例模式均可以改形成一种单线程模式,改造方法就是让其 implements Runnable 或者 extends Thread 重写run()方法便可,所以再也不举例...app

很显然 单线程模式 适应的场景为:一个始终运行(死循环)的单个线程,好比一个永不中止的单个后台线程,在后台实现一些辅助功能,或者实现垃圾回收之类的功能。有不容许多个线程执行的要求。好比本文中的刷新微信的access_token,就没有必要用多个线程不断的去刷新了,并且这样会形成混乱,不知道那个线程得到的access_token才是正确的(由于后一个线程得到的access_token会覆盖前一个的)。ide

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值