记得刚毕业的时候笔试或者面试通常会出现这样的问题“JAVA多线程有几种实现方式”,于是果断写下有两种,继承Thread抽象类或者实现Runnable接口。
但是当我们真正的观察Thread类的时候发现其实Thread也继承Runnable接口
public class Thread implements Runnable{
......
Runnable 接口更加简单,留下一个抽象方法之后就不负责任了。
public interface Runnable
{
public abstract void run();
}
考虑到上面问题,那我们可以不可以直接说,实现多线程的方式只有一种,那就是实现Runnable接口呢。
这个问题没有答案,因为从继承和实现的角度来说是对的,但是,如果只实现一个Runnable接口就是一个多线程了那么多线真的太简单了。
还记得实现Runnable之后还要做什么吗?需要把这个对象作为参数放入Thread类中,然后调用start方法。
new Thread(new MyRunnable()).start();
所以说没有Thread类,就算你实现了Runnable()接口之后这个类也不过是个普通的类而已。
我们仔细看Thread类发现,多线程的逻辑都在这个类中,当然里面还有很多内部类和本地方法(JNI)。
因为里面关键的代码都是JNI的所以我们无法从源代码中知道更多的信息。
重要点的方法有两个,一个是构造方法中调用的初始化方法
private void init(ThreadGroup threadgroup, Runnable runnable, String s, long l)
{
if(s == null)
throw new NullPointerException("name cannot be null");
Thread thread = currentThread();
SecurityManager securitymanager = System.getSecurityManager();
if(threadgroup == null)
{
if(securitymanager != null)
threadgroup = securitymanager.getThreadGroup();
if(threadgroup == null)
threadgroup = thread.getThreadGroup();
}
threadgroup.checkAccess();
if(securitymanager != null && isCCLOverridden(getClass()))
securitymanager.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
threadgroup.addUnstarted();
group = threadgroup;
daemon = thread.isDaemon();
priority = thread.getPriority();
name = s.toCharArray();
if(securitymanager == null || isCCLOverridden(thread.getClass()))
contextClassLoader = thread.getContextClassLoader();
else
contextClassLoader = thread.contextClassLoader;
inheritedAccessControlContext = AccessController.getContext();
target = runnable;
setPriority(priority);
if(thread.inheritableThreadLocals != null)
inheritableThreadLocals = ThreadLocal.createInheritedMap(thread.inheritableThreadLocals);
stackSize = l;
tid = nextThreadID();
}
另外一个是调用start()的时候
public synchronized void start()
{
boolean flag;
if(threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
flag = false;
start0();
flag = true;
try
{
if(!flag)
group.threadStartFailed(this);
}
catch(Throwable throwable) { }
break MISSING_BLOCK_LABEL_70;
Exception exception;
exception;
try
{
if(!flag)
group.threadStartFailed(this);
}
catch(Throwable throwable1) { }
throw exception;
}
private native void start0();