Java Thread 源码解析
来源:互联网 发布:四川广电网络客服电话 编辑:程序博客网 时间:2024/06/05 23:51
Thread 源码解析
线程的方法大部分都是使用Native使用,不允许应用层修改,是CPU调度的最基本单元。线程的资源开销相对于进程的开销是相对较少的,所以我们一般创建线程执行,而不是进程执行。
Thread 构造方法
/** * Initializes a Thread. * * @param g the Thread group * @param target the object whose run() method gets called * @param name the name of the new Thread * @param stackSize the desired stack size for the new thread, or * zero to indicate that this parameter is to be ignored. */private void init(ThreadGroup g, Runnable target, String name, long stackSize) { Thread parent = currentThread(); if (g == null) { g = parent.getThreadGroup(); } g.addUnstarted(); this.group = g; this.target = target; this.priority = parent.getPriority(); this.daemon = parent.isDaemon(); setName(name); init2(parent); /* Stash the specified stack size in case the VM cares */ this.stackSize = stackSize; tid = nextThreadID();}/** * Throws CloneNotSupportedException as a Thread can not be meaningfully * cloned. Construct a new Thread instead. * * @throws CloneNotSupportedException * always */@Overrideprotected Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException();}public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0);}public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0);}public Thread(ThreadGroup group, Runnable target) { init(group, target, "Thread-" + nextThreadNum(), 0);}public Thread(String name) { init(null, null, name, 0);}public Thread(ThreadGroup group, String name) { init(group, null, name, 0);}/** @hide */// Android added : Private constructor - used by the runtime.Thread(ThreadGroup group, String name, int priority, boolean daemon) { this.group = group; this.group.addUnstarted(); // Must be tolerant of threads without a name. if (name == null) { name = "Thread-" + nextThreadNum(); } // NOTE: Resist the temptation to call setName() here. This constructor is only called // by the runtime to construct peers for threads that have attached via JNI and it's // undesirable to clobber their natively set name. this.name = name; this.priority = priority; this.daemon = daemon; init2(currentThread()); tid = nextThreadID();}private void init2(Thread parent) { this.contextClassLoader = parent.getContextClassLoader(); this.inheritedAccessControlContext = AccessController.getContext(); if (parent.inheritableThreadLocals != null) { this.inheritableThreadLocals = ThreadLocal.createInheritedMap( parent.inheritableThreadLocals); }}public Thread(Runnable target, String name) { init(null, target, name, 0);}public Thread(ThreadGroup group, Runnable target, String name) { init(group, target, name, 0);}public Thread(ThreadGroup group, Runnable target, String name, long stackSize) { init(group, target, name, stackSize);}
Thread 中构造方法好好多种,如果在构造方法中没有传入线程name,那么Thread类中是会默认的为我们规定线程名字,即调用的是Thread- nextThreadNum(),对线程进行编号。 这个方法是同步的,保证了在执行的时候不会进行异步操作,避免了产生有相同的线ID的出现。在构造方法中都执行了init()方法, init 方法是私有的,会判断ThreadGroup 是否为空。
Thread的是实现了Runnable接口的,run 方法应该是怎么执行的?
@Overridepublic void run() { if (target != null) { target.run(); }}
run 方法中的target 变量就是我们在初始化的时候传入的变量,如果子类复写了run 方法,就不会调用target.run()
Thread 中重要的方法:
start() 方法
/** * Causes this thread to begin execution; the Java Virtual Machine * calls the <code>run</code> method of this thread. * <p> * The result is that two threads are running concurrently: the * current thread (which returns from the call to the * <code>start</code> method) and the other thread (which executes its * <code>run</code> method). * <p> * It is never legal to start a thread more than once. * In particular, a thread may not be restarted once it has completed * execution. * * @exception IllegalThreadStateException if the thread was already * started. * @see #run() * @see #stop() */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". */ 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); started = false; try { nativeCreate(this, stackSize, daemon); 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( )方法是同步的,并且是启动这个线程进行执行,Java虚拟机将会调用这个线程的run方法,这样产生的结果是,两个线程执行着,其中一个是调用start()方法的线程执行,另一个线程是执行run方法的线程。在start()方法中,首先进行的线程状态的判断,如果是一个JVM新启动的线程,那么threadStatus 的状态是为0的,如果线程不为0 将报出异常, 然后将线程添加到group中, group.add(this)方法中执行的结果是,通知group, 这个线程要执行了,所以可以添加进group中,然后调用本地方法nativeCreate(this, stackSize, daemon);
sleep() 方法
/** * Causes the currently executing thread to sleep (temporarily cease * execution) for the specified number of milliseconds plus the specified * number of nanoseconds, subject to the precision and accuracy of system * timers and schedulers. The thread does not lose ownership of any * monitors. * * @param millis * the length of time to sleep in milliseconds * * @param nanos * {@code 0-999999} additional nanoseconds to sleep * * @throws IllegalArgumentException * if the value of {@code millis} is negative, or the value of * {@code nanos} is not in the range {@code 0-999999} * * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */public static void sleep(long millis, int nanos)throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("millis < 0: " + millis); } if (nanos < 0) { throw new IllegalArgumentException("nanos < 0: " + nanos); } if (nanos > 999999) { throw new IllegalArgumentException("nanos > 999999: " + nanos); } // The JLS 3rd edition, section 17.9 says: "...sleep for zero // time...need not have observable effects." if (millis == 0 && nanos == 0) { // ...but we still have to handle being interrupted. if (Thread.interrupted()) { throw new InterruptedException(); } return; } long start = System.nanoTime(); long duration = (millis * NANOS_PER_MILLI) + nanos; Object lock = currentThread().lock; // Wait may return early, so loop until sleep duration passes. synchronized (lock) { while (true) { sleep(lock, millis, nanos); long now = System.nanoTime(); long elapsed = now - start; if (elapsed >= duration) { break; } duration -= elapsed; start = now; millis = duration / NANOS_PER_MILLI; nanos = (int) (duration % NANOS_PER_MILLI); } }}
sleep()方法在使用线程的时候,用的是比较多的。 这个方法的作用使得当前线程休眠一定的时间,但是这个期间是不释放持有的锁的。这个方法里面首先进行的是休眠时间的判断,然后又是调用本地方法。
join()方法
/** * Waits at most {@code millis} milliseconds for this thread to * die. A timeout of {@code 0} means to wait forever. * * <p> This implementation uses a loop of {@code this.wait} calls * conditioned on {@code this.isAlive}. As a thread terminates the * {@code this.notifyAll} method is invoked. It is recommended that * applications not use {@code wait}, {@code notify}, or * {@code notifyAll} on {@code Thread} instances. * * @param millis * the time to wait in milliseconds * * @throws IllegalArgumentException * if the value of {@code millis} is negative * * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */public final void join(long millis) throws InterruptedException { synchronized(lock) { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { lock.wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } lock.wait(delay); now = System.currentTimeMillis() - base; } } }}
join方法是等待该线程执行,直到超时或者终止,可以作为线程通信的一种方式,A线程调用B线程的join(阻塞),等待B完成后再往下执行
interrupt()方法
public void interrupt() { if (this != Thread.currentThread()) checkAccess(); synchronized (blockerLock) { Interruptible b = blocker; if (b != null) { nativeInterrupt(); b.interrupt(this); return; } } nativeInterrupt();}
interrupt()方法是中断当前的线程,一般来说,阻塞函数:如Thread.sleep、Thread.join、Object.wait等在检查到线程的中断状态的时候,会抛出InteruptedExeption, 同时会清除线程的中断状态。
线程状态
/** * A thread state. A thread can be in one of the following states: * <ul> * <li>{@link #NEW}<br> * A thread that has not yet started is in this state. * </li> * <li>{@link #RUNNABLE}<br> * A thread executing in the Java virtual machine is in this state. * </li> * <li>{@link #BLOCKED}<br> * A thread that is blocked waiting for a monitor lock * is in this state. * </li> * <li>{@link #WAITING}<br> * A thread that is waiting indefinitely for another thread to * perform a particular action is in this state. * </li> * <li>{@link #TIMED_WAITING}<br> * A thread that is waiting for another thread to perform an action * for up to a specified waiting time is in this state. * </li> * <li>{@link #TERMINATED}<br> * A thread that has exited is in this state. * </li> * </ul> * * <p> * A thread can be in only one state at a given point in time. * These states are virtual machine states which do not reflect * any operating system thread states. * * @since 1.5 * @see #getState */public enum State { /** * Thread state for a thread which has not yet started. */ NEW, /** * Thread state for a runnable thread. A thread in the runnable * state is executing in the Java virtual machine but it may * be waiting for other resources from the operating system * such as processor. */ RUNNABLE, /** * Thread state for a thread blocked waiting for a monitor lock. * A thread in the blocked state is waiting for a monitor lock * to enter a synchronized block/method or * reenter a synchronized block/method after calling * {@link Object#wait() Object.wait}. */ BLOCKED, /** * Thread state for a waiting thread. * A thread is in the waiting state due to calling one of the * following methods: * <ul> * <li>{@link Object#wait() Object.wait} with no timeout</li> * <li>{@link #join() Thread.join} with no timeout</li> * <li>{@link LockSupport#park() LockSupport.park}</li> * </ul> * * <p>A thread in the waiting state is waiting for another thread to * perform a particular action. * * For example, a thread that has called <tt>Object.wait()</tt> * on an object is waiting for another thread to call * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on * that object. A thread that has called <tt>Thread.join()</tt> * is waiting for a specified thread to terminate. */ WAITING, /** * Thread state for a waiting thread with a specified waiting time. * A thread is in the timed waiting state due to calling one of * the following methods with a specified positive waiting time: * <ul> * <li>{@link #sleep Thread.sleep}</li> * <li>{@link Object#wait(long) Object.wait} with timeout</li> * <li>{@link #join(long) Thread.join} with timeout</li> * <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li> * <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li> * </ul> */ TIMED_WAITING, /** * Thread state for a terminated thread. * The thread has completed execution. */ TERMINATED;}
1、NEW
新建立的线程,还没有调用start()方法
2、 RUNNABLE
可以运行,需要再等到其他资源(如CPU)就绪才能运行
3、 BLOCKED
线程调用wait()后等待内置锁进入同步方法或块中
4、WAITING
在调用无参的wait(),Thread.join()
5、TIMED_WAITING
调用Thread.sleep(), 有时间参数的wait(), 有时间参数的Thread.join()
6、TERMINATED
执行完毕的线程状态
- Java Thread 源码解析
- java thread join 源码解析
- Thread源码解析
- Thread类(Java多线程操作之Thread类,源码解析)
- JDK8中Thread源码解析
- Java Thread源码分析
- java Thread 源码分析
- java Thread源码分析
- Java Thread 源码 附录
- java thread源码分析
- 《JAVA源码分析》:Thread
- java里的 thread 源码
- Java中Thread源码剖析
- Java Thread(Android Nougat源码)
- bind源码解析(socket,thread)
- LK源码解析 3 thread.c
- Java源码心中有数系列 java.lang.thread
- JAVA源码解析-String源码
- JAVA——IO流 之 字节流与字符流(1)
- 统计学习方法读书笔记--4.朴素贝叶斯法
- String,StringBuffer与StringBuilder的区别
- latex总结
- 汉诺塔III
- Java Thread 源码解析
- [每日问答]特征选择有哪些方法?
- ReactNative学习历程
- 利用 Profiler(性能分析器)查看游戏在移动真机上的性能消耗数据
- 剑指offer——二叉树的深度
- 字符数组和字符串的区别
- 库存管理系统中登录验证中出现的问题
- 1038. 统计同成绩学生(20)
- Ureal编译器的快捷使用