初识多线程
1,概述
这篇文章主要介绍下Thread的源码以及一些概念。并发编程涉及的点有很多,如线程的创建和使用,如何控制线程间的通信,syschronized、volatile的使用以及原理,Atomic原子系列的使用以及原理,锁的实现原理(AQS)以及优化,并发包下的安全的集合以及原理,线程池的使用以及实现原理等等。后面我们依次慢慢来解读。这篇文章就是简单看下Thread的源码和启动线程的过程。
2,创建Thread的源码:
thread()构造函数有很多,我们这次就看看默认的构造函数都有哪些操作,然后学学一些概念即可。其他的构造函数都是雷同的
public Thread() {
#这里第一个变量表示线程组,第三个变量表示线程名称。每个线程都是属于一个线程组的,每个线程也有名称。 init(null, null, "Thread-" + nextThreadNum(), 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) {
#从这里说明我们可以给线程取名字,要么就是默认的名称:Thread-0 Thread-1这样的结构 if (name == null) { throw new NullPointerException("name cannot be null"); } this.name = name; #每个线程都是有父线程的,默认的父线程就是当前创建你的线程。比如在main线程创建了一个线程Thread-0,那么Thread-0的父线程就是线程mian Thread parent = currentThread(); SecurityManager security = System.getSecurityManager();
#刚刚说到每个线程都是属于一个线程组的,这一段表示线程的线程组默认就是父线程的线程组 if (g == null) { /* Determine if it's an applet or not */ /* If there is a security manager, ask the security manager what to do. */ if (security != null) { g = security.getThreadGroup(); } /* If the security doesn't have a strong opinion of the matter use the parent thread group. */ if (g == null) { g = parent.getThreadGroup(); } } /* checkAccess regardless of whether or not threadgroup is explicitly passed in. */ g.checkAccess(); /* * Do we have the required permissions? */ if (security != null) { if (isCCLOverridden(getClass())) { security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); } } g.addUnstarted(); #线程的线程组默认是父线程的线程组 this.group = g;
#线程是否是daemon也是取决于父类 this.daemon = parent.isDaemon(); this.priority = parent.getPriority(); 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); if (inheritThreadLocals && parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); /* Stash the specified stack size in case the VM cares */ this.stackSize = stackSize; /* Set thread ID */ tid = nextThreadID(); }
从构造函数需要学习的点:
1,线程都是有名称的,默认就是这样Thread-0,Thread-1这样子。
2,每个线程都是有父线程的,父线程就是当前创建你的线程。每个线程都是有线程组的,如果不指定就默认是父线程的线程组。
3,线程是有有工作线程和后台线程的。如果工作线程没有关闭,JVM不会退出。而如果只有后台线程在执行却没有工作线程在运行,JVM进程就会退出。
3,线程的执行
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". */
#同一个线程只能被start一次,多次start就报如下异常了
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 {
#这是native()方法,也就是把线程启动了,就不深究下去了 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 */ } } }
start()方法学习的点:
同一个线程只能执行一次start()方法,否则会报异常。
4,最后
我没有写怎么创建线程这些基本的操作,主要只是想看看源码部分,操作类的动作自行百度一下就好了。
Thread-