【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程序我也使用过匿名内部类,只是自己没有注意到这个概念。

时间: 2024-12-28 04:42:21

【Java】定时器、线程与匿名内部类的相关文章

Java的线程和多线程教程

Java线程(Java Thread)是执行某些任务的一种轻量级进程.Java中的Thread类提供了多线程(multi-threading)功能,应用程序能够创建多个线程并同一时候执行. 在一个应用程序中,一般会有两种类型的线程-用户线程(user thread)和守护线程(daemon thread).当我们启动引用程序时,首先创建用户线程main,我们能够创建多个用户线程和守护线程.当全部的用户线程都运行完成时,JVM就会终止程序. 对不同的线程,我们能够设置对应的优先级,但并不意味着高优

整理:java定时器。

本文纯属个人思路,如有错误,请指正. java的Timer依赖Thread,每一个Timer实际上都是一个Thread. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import java.util.TimerTask; /**  * 本类仅为实现TimerTask,意义不大.  * @author 9082046**@qq.com  *  */ public class Task  extends TimerTask {       public void run()

Java多线程基础(四)Java传统线程同步通信技术

Java多线程基础(四)Java传统线程同步通信技术 编写代码实现以下功能 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着再回到主线程又循环100次,如此循环50次. 分析 1)子线程循环10次与主线程循环100次必须是互斥的执行,不能出现交叉,下面代码中通过synchronized关键字实现此要求: 2)子线程与主线程必须交替出现,可以通过线程同步通信技术实现,下面代码中通过bShouldSub变量实现此要求: 其他需要注意的地方 1)其中business变量必须声

java定时器

以下内容根据 JavaTM Tutorial 和相关API doc和网上的资料翻译整理,以供日后查看和参考: 1.描述 Timer是一种定时器工具,用来在一个后台线程计划执行指定任务.它可以计划执行一个任务一次或反复多次. TimerTask一个抽象类,它的子类代表一个可以被Timer计划的任务. 简单的一个例程: import java.util.Timer; import java.util.TimerTask; /** * Simple demo that uses java.util.T

Java定时器的使用(Timer简介)

在开发中,我们经常需要一些周期性的操作,例如每隔几分钟就进行某一项操作.这时候我们就要去设置个定时器,Java中最方便.最高效的实现方式是用java.util.Timer工具类,再通过调度java.util.TimerTask任务. 1.简介 Timer是一种工具,线程用其安排以后在后台线程中执行的任务.可安排任务执行一次,或者定期重复执行.实际上是个线程,定时调度所拥有的TimerTasks. TimerTask是一个抽象类,它的子类由 Timer 安排为一次执行或重复执行的任务.实际上就是一

我的第一个java定时器

在开发中,我们经常需要一些周期性的操作,例如每隔几分钟就进行某一项操作.这时候我们就要去设置个定时, 接下来就去开发我的第一个java定时器吧,Java计时器实用程序允许您执行线程或任务在一个预先确定的将来的时间,并根据一组这些任务可以重复频率. 设计和实现一个计时器,会用到model-control-view(MVC)设计模式. 开始: 首先来构w建一个最简单的java web 项目吧.这里我用的是最myeclipse,好处自然不必多说,谁用谁知道,当然如果 你要用其他IDE也可以. 在mye

java定时器的使用

java定时器的使用(Timer) 1.在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等. 对于这样的操作最方便.高效的实现方式就是使用java.util.Timer工具类. privatejava.util.Timer timer; timer = newTimer(true); timer.schedule( newjava.util.TimerTask() { public void run() {//server.checkNewMail(); 要操作的方法} }, 0

Java中线程封闭之ThreadLocal

在访问共享数据时通常使用同步.若不使用同步则可以将对象封闭在一个线程中达到线程安全的目的,该方法称为线程封闭(Thread Confinement).其中实现线程封闭中规范的方法是使用ThreadLocal类.线程封闭技术一种常用的使用场景是在JDBC Connection对象. public class ConnectionHelper{private final static String URL = "";private final static ThreadLocal<C

Java多线程系列一——Java实现线程方法

Java实现线程的两种方法 继承Thread类 实现Runnable接口 它们之间的区别如下: 1)Java的类为单继承,但可以实现多个接口,因此Runnable可能在某些场景比Thread更适用2)Thread实现了Runnable接口,并且有更多实用方法3)实现Runnable接口的线程启动时仍然需要依赖Thread import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.junit.As