【Java】定时器、线程与匿名内部类

内部匿名类在一些Java书籍中写得非常抽象,其实这东西,如果单独拿出来讲的话,也确实很难讲得通,我本来以为如此抽象的概念,并没有什么用。万万没想到到是,这东西在安卓编程的监听器中使用得尤其之多。匿名内部类根本一点都不难,大家一直在用,却一直都不知道自己在用,被问到这个概念就懵了。如果你用过jQuery,你一定见过如下的结构:

$("#组件id").click(function(){
    //要做的事情
}); 
这里组件id被点击的监听器function(){}就是一个匿名内部函数。

好吧,如果你用过jQuery,那么,我将会以如下的一个小例子来说明这个问题。


定义一个定时器,每1秒把i自加。再定义一个线程,每5秒检查i是否超过3,如果i超过3,则把定时器停止,同时自己自然死亡。

定时器的使用在《【Java】利用Timer与TimerTask定时执行任务》(点击打开链接)已经说过了,线程的使用也在《【Java】线程并发、互斥与同步》(点击打开链接)讨论过了。

本来如果要在Java中使用定时器,线程要写较长的代码的,先new一个定时器或者线程,然后再开一个继承定时器、线程抽象接口的类,重写里面的方法。

但是,如果你使用了匿名内部类,上图的程序的代码,则演变成这样:

import java.util.*;

public class timerTheardTest {
	private static int i = 0;
	private static Timer timer;

	public static void main(String[] args) {
		timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			// 如果这里出现int i=2;这个i将会作用于这个匿名内部类的所有方法
			// 上面的private static int i=0;失效
			// 请注意,此时出现int i=2,是没有语法错误的!
			public void run() {
				System.out.println(i++);
			}
		}, 0, 1000);

		new Thread(new Runnable() {
			@Override
			//在Runnable中,如果要让线程自己一直跑下去,必须自己定义while结构
			//如果这个run()方法读完了,则整个线程自然死亡
			public void run() {	
				//定义一个线程中止标志
				boolean isContinue = true;
				while (isContinue) {
					try {
						Thread.sleep(5000);//Java中线程的休眠,必须在try-catch结构中
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if (i > 3) {
						timer.cancel();//中止定时器
						isContinue = false;//跳出这个死循环,让线程自然死亡
					}
				}
			}
		}).start();//默认线程不启动,必须自己start()
	}
}

程序先定义两个覆盖与整个主类的全局变量,一个自增的i,一个定时器timer。自增i要被定时器、线程同时操作,所以成为全局变量是一定的。有人可能疑惑为何定时器timer也要是全局变量。那是因为在线程中有中止定时器的方法。如果你在主函数中才定义定时器,其作用范围无法覆盖到线程中Runnable这个匿名内部类。

之后,非常清晰地可以看到,本来定时器第一个参数必须填上一个继承TimerTask的类,为了配合,我们原本要又要开一个类,同时为这个类命名,再放到这里,但是由于使用了匿名内部类的出现,现在可以直接重现。线程也是如此。这里非常想jQuery、ExtJs的Javascript前端框架的结构。安卓的组件监听器其实也在大量使用匿名内部类。

其实,以前的在《【Java】Collections中sort方法Comparator的重写》(点击打开链接)的Java程序我也使用过匿名内部类,只是自己没有注意到这个概念。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,可以使用多线程和定时器来实现定时任务。你可以通过创建一个继承自Thread类或实现Runnable接口的类来定义一个线程,并在run方法中编写线程的执行逻辑。然后,使用定时器类Timer或ScheduledThreadPoolExecutor来调度线程的执行。 下面是一个使用定时器类Timer实现定时任务的示例代码: ```java import java.util.Timer; import java.util.TimerTask; public class MyTask extends TimerTask { public void run() { // 在这里写定时任务的逻辑 System.out.println("定时任务执行了"); } public static void main(String[] args) { Timer timer = new Timer(); MyTask task = new MyTask(); // 延迟1秒后开始执行任务,每隔2秒执行一次 timer.schedule(task, 1000, 2000); } } ``` 在上面的示例中,首先定义了一个继承自TimerTask的类MyTask,重写了run方法,在run方法中编写了定时任务的逻辑。然后,在main方法中创建了一个Timer对象和一个MyTask对象,使用schedule方法指定了任务的延迟时间和执行间隔。 当程序运行时,定时任务会在延迟1秒后开始执行,并且每隔2秒执行一次。你可以根据实际需求修改延迟时间和执行间隔。 除了使用Timer类,你还可以使用ScheduledThreadPoolExecutor类来实现定时任务。这个类提供了更灵活的定时任务调度方式,可以满足更多复杂的需求。你可以根据自己的需求选择适合的方式来实现Java线定时器

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值