3.2 实现 Runnable 接口
这是实现 Runnable 的接口,并作为 Thread 构造器的入参,调用时我们使用了两种方式,可以根据实际情况择一而终
- 使用 start 会开启子线程来执行 run 里面的内容
- 使用 run 方法执行的还是主线程。
我们来看下 run 方法的源码:
- 不会新起线程,target 是 Runnable
- 源码中的 target 就是在 new Thread 时,赋值的 Runnable。
4 线程的初始化
线程初始化的源码有点长,我们只看比较重要的代码 (不重要的被我删掉了),如下:
// 无参构造器,线程名字自动生成 public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); } // g 代表线程组,线程组可以对组内的线程进行批量的操作,比如批量的打断 interrupt // target 是我们要运行的对象 // name 我们可以自己传,如果不传默认是 "Thread-" + nextThreadNum(),nextThreadNum 方法返回的是自增的数字 // stackSize 可以设置堆栈的大小 private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) { if (name == null) { throw new NullPointerException("name cannot be null"); } this.name = name.toCharArray(); // 当前线程作为父线程 Thread parent = currentThread(); this.group = g; // 子线程会继承父线程的守护属性 this.daemon = parent.isDaemon(); // 子线程继承父线程的优先级属性 this.priority = parent.getPriority(); // classLoader if (security == null || isCCLOverridden(parent.getClass())) this.contextClassLoader = parent.getContextClassLoader(); else this.contextClassLoader = parent.contextClassLoader; this.inheritedAccessControlContext = acc != null ? acc : AccessController.getContext(); this.target = target; setPriority(priority); // 当父线程的 inheritableThreadLocals 的属性值不为空时 // 会把 inheritableThreadLocals 里面的值全部传递给子线程 if (parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); this.stackSize = stackSize; /* Set thread ID */ // 线程 id 自增 tid = nextThreadID(); }
从初始化源码中可以看到,很多属性,子线程都是直接继承父线程的,包括优先性、守护线程、inheritableThreadLocals 里面的值等等。
5 线程其他操作
5.1 join
当前线程等待另一个线程执行死亡之后,才能继续操作。
public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }
等待最多 millis 毫秒以使该线程消失。 0 超时时间意味着永远等待。
此实现使用以 this.isAlive 为条件的 this.wait 调用循环。当线程终止时,将调用this.notifyAll方法。 建议应用程序不要在线程实例上使用 wait,notify 或 notifyAll。

