在学习Java的路上很早很早就接触了回调,比如:JFrame的键盘事件,JFrame控件的点击事件,线程池执行之前的方法beforeExecute与执行之后的方法 afterExecute,线程的Run方法其原理就是使用了回调。之前一直没有研究过其原理,在这里学习一下回调模式,也方便理解事件监听模式和观察者模式。
在计算机程序设计中,回调函数,或简称回调,是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序
可能会有这样一个需求,某开发者想在线程执行之前和执行之后分别做一些事情,你可能想到的方法就是在线程的run方法体内做这些操作,这样固然能实现,可是却使得各种业务耦合在一起。最好的解决方法就是使用回调模式。
定义一个抽象类ThreadHolder 在抽象类中有三个方法
abstract class ThreadHolder {
public final void run(Runnable runnable) {
Objects.requireNonNull(runnable, "runnable required not null");
beforeRun();
runnable.run();
afterRun();
}
/**
* 在线程执行之前执行
*/
protected void beforeRun() {
}
/**
* 在线程执行完之后执行
*/
protected void afterRun() {
}
}
然后实现一个简单的线程任务,继承ThreadHolder 并重写beforeRun和afterRun方法
class simpleThread extends ThreadHolder {
@Override
protected void beforeRun() {
System.out.println("执行之前。。。");
}
@Override
protected void afterRun() {
System.out.println("执行之后。。。");
}
}</span class="hljs-inheritance">
测试
public class AppTest {
public static void main(String[] args) {
simpleThread simpleThread = new simpleThread();
simpleThread.run(() -> {
int n = 10;
for (int i = 0; i < n; i++) {
System.out.println("current num is :" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
测试结果:
执行之前。。。 current num is :0 current num is :1 current num is :2 current num is :3 current num is :4 current num is :5 current num is :6 current num is :7 current num is :8 current num is :9 执行之后。。。
解释:
通过这个实例,我们可以看到使用回调模式实现了我们的功能。在底层代码,即ThreadHolder中我们就制定了空方法执行顺序,在高层重写空的方法,然后在执行时我们实现的方法就会被底层调用。
今天小程序更新的题库:(在文章结束稍稍提及一点,题库的作用其实并非完全是为了面试,更多的是让我们进行知识的扩展。)
1.回调模式在不在23中设计模式当中?
2.23种设计模式你能罗列出来几种?
3.设计模式遵循的原则你知道吗?
4.有没有对ThreadLocal与线程同步机制进行比较?
5.你知道Netty关于ThreadLocal机制的优化吗?