一个方法连续调用多次,但方法体里面的代码只保证最后一次的执行,之前连续调用的方法体都不执行

  以后有遇上这种需求,值得借鉴
  模拟场景1: 假设需求说:只要我点播放音乐,5分钟后就把这音乐给我播放。
  需要考虑的问题:如果用户断断续续按20次,怎么办?
  需求又说:这种问题好办,他点20次,你就让他点的最后一次的5分钟后再播放音乐,之前的19次就别播放了接下来,
  就可以用这个java类了,20次就是对应本类的call联系调用20次,5分钟后对应sleep,5分钟后播放对应@link {@link Listener}中的call 


/**
 * 最后线程执行
 * 
 * <p>
 * 一个方法连续调用多次,但方法体里面的代码只保证最后一次的执行,之前连续调用的方法体都不执行
 * 
 * @author 更生
 * @version 2016年5月9日
 */
public class LastThread {

	private long sleep;// 需要睡眠多久

	private Listener listenr;// 回调

	private Object value;// 携带对象

	private int count = 0;// 线程标识

	private Thread curr;// 当前正在执行的线程

	public static final int END = -1;// 回调标记

	public static final int START = 1; // 回调标记为开始

	public LastThread(Listener listenr) {
		this.listenr = listenr;
	}

	/**
	 * 调用此方法会启动一个新线程,如果在新线程之前还有旧线程没睡醒,那么旧线程的call方法就不会调用
	 * <P>
	 * 假设: 9点20调用call生成一个线程T1,T1会睡眠2分钟 9点21再次调用call生成一个线程A2 由于T1没有睡醒,call方法就被再次调用,所以T1的{@link Lisntern}
	 * 中的call不会执行,只执行了T2的 {@link Lisntern}中的call 最后结果:{@link LastThread}中的call 调用了两次,但是 {@link Lisntern}中的call只执行了一次
	 * 
	 * @param obj 允许携带的参数,@link {@link Listener}
	 */
	public void call(Object obj) {
		start(obj);
	}

	/**
	 * 在call 之前调用,线程睡醒后才会执行{@link Listener }中方法的call
	 * 
	 * @param sleep 毫秒
	 */
	public void setSleep(long sleep) {
		this.sleep = sleep;
	}

	/**
	 * 携带参数
	 * 
	 * @param value
	 */
	public void setValue(Object value) {
		this.value = value;
	}

	/**
	 * 停止所有没睡醒的线程
	 */
	public void cancel() {
		allowExcuteVersion();
		stop();
	}

	// 真正处理逻辑
	private void start(final Object obj) {
		allowExcuteVersion();
		stop();

		curr = new Thread(new Runnable() {

			public void run() {
				if (sleep > 0) {
					try {
						Thread.sleep(sleep);
					} catch (InterruptedException e) {
						e.printStackTrace();
						return;
					}
				}
				Thread currentThread = Thread.currentThread();

				boolean return1 = isReturn(currentThread);
				if (return1) {
					if (listenr != null) {
						listenr.call(END, value);
					}
					return;
				}

				if (listenr != null) {
					listenr.call(START, obj);
				}

			}
		});
		curr.setName(count + "");
		curr.start();
	}

	// 最新线程的标记
	private void allowExcuteVersion() {
		count++;
	}

	// 停止当前的线程
	private void stop() {
		if (curr != null) {
			try {
				curr.stop();
			} catch (Exception e) {
			}
		}
	}

	/**
	 * 是否调用线程的{@link Listener}中call
	 * 
	 * @param thread
	 * @return
	 */
	private boolean isReturn(Thread thread) {
		String name = thread.getName();
		int curr = Integer.valueOf(name);
		if (curr < count) {
			return true;
		}
		return false;
	}
}

public interface Listener {

	public Object call(int flag, Object obj);

}


  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值