问题:如果在Thread子类覆盖的run方法中编写了运行代码,也为Thread子类对象传递了一个Runnable对象,那么,线程运行时的执行代码是子类的run方法的代码?还是Runnable对象的run方法的代码呢?
下面,展示一段代码来说明问题:
public class ThreadAndRunnable {
public static void main(String[] args) {
new Thread(new Runnable() {
/**
* 重写Runnable中的run方法
*/
@Override
public void run() {
while(true){
System.out.println("Runnable:"+Thread.currentThread().getName());
}
}
}){
/**
* 重写Thread中的run方法
*/
@Override
public void run() {
while(true){
System.out.println("Thread:"+Thread.currentThread().getName());
}
}
}.start();
}
}
大家可以先猜想一下,上面这段代码的运行结果是什么?(提示:涉及到一个知识点--匿名内部类对象的构造方法如何调用父类的非默认构造方法)
先看一下运行结果是否和你猜想的一样:
从上图可知,当我们在Thread子类覆盖的run方法中编写了运行代码,也为Thread子类对象传递了一个Runnable对象,那么,线程运行时的执行代码是子类的run方法的代码!!!
我们可以从Thread的源码来进行简单分析一下:
package java.lang;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import sun.misc.Contended;
import sun.misc.VM;
import sun.nio.ch.Interruptible;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
public class Thread
implements Runnable
{
private volatile char[] name;
private int priority;
private Thread threadQ;
private long eetop;
private boolean single_step;
private boolean daemon = false;
private boolean stillborn = false;
private Runnable target;
private ThreadGroup group;
private ClassLoader contextClassLoader;
private AccessControlContext inheritedAccessControlContext;
private static int threadInitNumber;
ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
private long stackSize;
private long nativeParkEventPointer;
private long tid;
private static long threadSeqNumber;
private volatile int threadStatus = 0;
volatile Object parkBlocker;
private volatile Interruptible blocker;
private final Object blockerLock = new Object();
public static final int MIN_PRIORITY = 1;
public static final int NORM_PRIORITY = 5;
public static final int MAX_PRIORITY = 10;
private static final StackTraceElement[] EMPTY_STACK_TRACE = new StackTraceElement[0];
private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION = new RuntimePermission("enableContextClassLoaderOverride");
private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
@Contended("tlr")
long threadLocalRandomSeed;
@Contended("tlr")
int threadLocalRandomProbe;
@Contended("tlr")
int threadLocalRandomSecondarySeed;
private static native void registerNatives();
private static synchronized int nextThreadNum()
{
return threadInitNumber++;
}
private static synchronized long nextThreadID()
{
return ++threadSeqNumber;
}
void blockedOn(Interruptible paramInterruptible)
{
synchronized (this.blockerLock)
{
this.blocker = paramInterruptible;
}
}
public static native Thread currentThread();
public static native void yield();
public static native void sleep(long paramLong)
throws InterruptedException;
public static void sleep(long paramLong, int paramInt)
throws InterruptedException
{
if (paramLong < 0L) {
throw new IllegalArgumentException("timeout value is negative");
}
if ((paramInt < 0) || (paramInt > 999999)) {
throw new IllegalArgumentException("nanosec