策略模式在Thread和Runnable中的应用

157 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

策略模式在Thread和Runnable中的应用

Runnable接口最重要的方法—–run方法,使用了策略者模式将执行的逻辑(run方法)和程序的执行单元(start0方法)分离出来,使用户可以定义自己的程序处理逻辑,更符合面向对象的思想。

Thread的构造方法

  • 创建线程对象Thread,默认有一个线程名,以Thread-开头,从0开始计数,如“Thread-0、Thread-1、Thread-2 …”
  • 如果没有传递Runnable或者没有覆写Thread的run方法,该Thread不会调用任何方法
  • 如果传递Runnable接口的实例或者覆写run方法,则会执行该方法的逻辑单元(逻辑代码)
  • 如果构造线程对象时,未传入ThreadGroup,Thread会默认获取父线程的ThreadGroup作为该线程的ThreadGroup,此时子线程和父线程会在同一个ThreadGroup中
  • stackSize可以提高线程栈的深度,放更多栈帧,但是会减少能创建的线程数目
  • stackSize默认是0,如果是0,代表着被忽略,该参数会被JNI函数调用,但是注意某些平台可能会失效,可以通过“-Xss10m”设置

具体的介绍可以看Java的API文档

/*下面是Thread 的部分源码*/

public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}

public Thread(String name) {
    init(null, null, name, 0);
}
		↓ ↓	↓	
         ↓ ↓	
          ↓	
private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
    init(g, target, name, stackSize, null, true);
}
		↓ ↓	↓	
         ↓ ↓	
          ↓	
private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
    //中间源码省略
    this.target = target;//①
}

/* What will be run. */
private Runnable target; //Thread类中的target属性

@Override
public void run() {
    if (target != null) { //②
        target.run();
    }
}

源码标记解读:

1、如果Thread类的构造方法传递了一个Runnable接口对象

①那么该接口对象将被Thread类中的target属性所保存。

②在start()方法执行的时候会调用Thread类中的run()方法。因为target不为null, target.run()就去调用实现Runnable接口的子类重写的run()。

2、如果Thread类的构造方传没传Runnable接口对象

①Thread类中的target属性保存的就是null。

②在start()方法执行的时候会调用Thread类中的run()方法。因为target为null,只能去调用继承Thread的子类所重写的run()。

JVM一旦启动,虚拟机栈的大小已经确定了。但是如果你创建Thread的时候传了stackSize(该线程占用的stack大小),该参数会被JNI函数去使用。如果没传这个参数,就默认为0,表示忽略这个参数。注:stackSize在有一些平台上是无效的。