Thread之模板模式
我们知道,在实际使用线程的时候,真正的执行逻辑都是写在run方法里面,run方法是线程的执行单元,如果我们直接使用Thread类实现多线程,那么run方法本身就是一个空的实现,如下:
/** * If this thread was constructed using a separate * <code>Runnable</code> run object, then that * <code>Runnable</code> object's <code>run</code> method is called; * otherwise, this method does nothing and returns. * <p> * Subclasses of <code>Thread</code> should override this method. * * @see #start() * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) */ @Override public void run() { if (target != null) { target.run(); } }
thread中start实现如下:
public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } }
回顾之前的《模板方法模式》不难看出,thread中的run和start是一个比较典型的模板模式,算法结构交由父类实现,具体的逻辑细节交由子类实现。
下面按照thread的run和start方式来实现一个简单的小demo,帮助大家理解。
代码如下:
package com.concurrency.designpattern.behavioral.templatemethod; /** * <p>Title: TemeplateMethod</p> * <p>Description: 参照thread的run和start方法,写的一个小demo</p> * <p>Company: http://www.yinjiedu.com</p> * <p>Project: annotation</p> * * @author: WEIQI * @Date: 2019-12-17 0:45 * @Version: 1.0 */ public class TemeplateMethod { /** * @description: 输出用户输入的字符串信息,类似于thread中的start() * @auther: WEIQI * @date: 2019-12-17 0:56 * @param inputString 用户输入字符串 */ public final void outputString(String inputString) { System.out.println("*******************"); userInput(inputString); System.out.println("*******************"); System.out.println(); } /** * @description: 暴露给继承类的方法,类似于thread中的run() * @auther: WEIQI * @date: 2019-12-17 0:57 * @param inputString 用户输入字符串 */ protected void userInput(String inputString) { } /** * @description: 编写简单的测试功能模块 * @auther: WEIQI * @date: 2019-12-17 0:58 */ public static void main(String[] args) { // 对象引用1,类似于创建一个线程 TemeplateMethod temeplateMethod1 = new TemeplateMethod(){ @Override protected void userInput(String inputString) { System.out.println(inputString); } }; // 第一个引用调用算法封装方法,类似于线程调用start()方法 temeplateMethod1.outputString("user1 input data"); // 对象引用2,类似于创建另外一个线程 TemeplateMethod temeplateMethod2 = new TemeplateMethod(){ @Override protected void userInput(String inputString) { System.out.println(inputString); } }; // 第二个引用调用算法封装方法,类似于线程调用start()方法 temeplateMethod2.outputString("user2 input data"); } }
运行结果:
在start方法申明时,加了synchronized 关键字保证了原子性,对于启动线程之前状态检查、加入线程组、调用native方法等都作为算法模板,由父类Thread完成。
想要了解实时博文,可以关注公众号《编程之艺术》
求知若饥,虚心若愚