一、Thread的定义:
public class Thread implements Runnable
Thread类实现了了Runnable接口。
Runnable接口源码:
public interface Runnable {
public abstract void run();
}
二、Thread的基本属性:
三、Thread的构造方法:
// 不带参数的默认构造方法
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
// 带一个参数:target - 任务
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
// 带两个参数:group - 线程组,target - 任务
public Thread(ThreadGroup group, Runnable target) {
init(group, target, "Thread-" + nextThreadNum(), 0);
}
// 带一个参数:name - 线程名称
public Thread(String name) {
init(null, null, name, 0);
}
// 带两个参数:group - 线程组,name - 线程名称
public Thread(ThreadGroup group, String name) {
init(group, null, name, 0);
}
// 带两个参数:target - 任务,name - 线程名称
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
// 带三个参数:group - 线程组,target - 任务,name - 线程名称
public Thread(ThreadGroup group, Runnable target, String name) {
init(group, target, name, 0);
}
// group - 线程组,target - 任务,name - 线程名称, stackSize - 栈大小
// 这里的stackSize只是提供一个参考值,和平台相关,JVM根据情况会做适当的调整。
// stackSize大一些,线程就会不容易抛StackOverflowError。
// stackSize小一些,多个线程并发执行不容易抛OutOfMemoryError。
// 栈大小,最大递归深度和并发水平是和平台相关的。
public Thread(ThreadGroup group, Runnable target, String name, long stackSize) {
init(group, target, name, stackSize);
}
构造方法里都调用了init方法,init方法代码如下:
/**
* 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.
*/
//ThreadGroup:线程组表示一个线程的集合。此外,线程组也可以包含其他线程组。线程组构成一棵树,在树中,除了初始线程组外,每个线程组都有一个父线程组。
private void init(ThreadGroup g, Runnable target, String name, long stackSize) {
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;
//每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
this.name = name.toCharArray();
if (security == null || isCCLOverridden(parent.getClass()))
this.contextClassLoader = parent.getContextClassLoader();
else
this.contextClassLoader = parent.contextClassLoader;
this.inheritedAccessControlContext = AccessController.getContext();
this.target = target;
setPriority(priority);
if (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();
}
在init 初始化时设置了是否为守护线程,优先级,初始化名称。
四、Thread的其他常用方法:
1. 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".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
start0();
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
改方法主要调用了start0方法:
private native void start0();
这里使用了本地调用,通过C代码初始化线程需要的系统资源。可见,线程底层的实现是通过C代码去完成的。
2. run:是实现Runnable接口的run方法,用来执行线程的操作。
一般由JVM来调用该方法,也可以手动调用。
a. 如果子类覆盖了run()方法,则调用子类的run()
b. 如果a不成立:
b1. 指定了target,则调用target的run() ;
b2. 没有指定target,该方法不做任何事并返回 。
public void run() {
if (target != null) {
target.run();
}
}
使用继承Thread创建线程类时,需要重写run方法,因为默认的run方法什么也不干。
private void exit() {
if (group != null) {
group.remove(this);
group = null;
}
target = null;
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
4. yield:使当前执行线程暂停一会,让其它线程得以执行。只是临时让出时间片,不会释放拥有的锁。
public static native void yield();
也是一个native方法。
5. sleep :使当前执行线程休眠指定的时间,不释放持有的锁。
public static native void sleep(long millis) throws InterruptedException;
public static void sleep(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && millis == 0)) { // 纳秒四舍五入,或者毫秒为0且纳秒不为0时
millis++;
}
sleep(millis);
}
6. join:等待该线程执行,直到超时或者终止。
可以作为线程通信的一种方式:A线程调用B线程的join方法(阻塞),等待B完成后再往下执行。
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) { // 0代表没有时间限制
while (isAlive()) {
wait(0); // 无限期的等待
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay); // 有限期的等待
now = System.currentTimeMillis() - base;
}
}
}
public final synchronized void join(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && millis == 0)) { // 纳秒四舍五入,或者毫秒为0且纳秒不为0时
millis++;
}
join(millis);
}
public final void join() throws InterruptedException {
join(0);
}
7. interrupt:中断一个线程。
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt();
return;
}
}
interrupt0();
}
// 静态方法:查看当前线程是否中断,并且清除中断标志。
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
// 查看该线程是否中断,但不清除中断标志。
public boolean isInterrupted() {
return isInterrupted(false);
}
private native boolean isInterrupted(boolean ClearInterrupted);
8. setPriority:设置线程的优先级。
// 最小的优先级
public final static int MIN_PRIORITY = 1;
// 正常的优先级
public final static int NORM_PRIORITY = 5;
// 最大的优先级
public final static int MAX_PRIORITY = 10;
public final void setPriority(int newPriority) {
ThreadGroup g;
checkAccess();
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
throw new IllegalArgumentException();
}
if((g = getThreadGroup()) != null) {
if (newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
setPriority0(priority = newPriority);
}
}
9. getState: 获取线程状态。
public enum State {
// 新建的线程,还没调用start()方法
NEW,
// 可以运行,需要等到其它资源(如CPU)就绪才能运行
RUNNABLE,
// 线程调用wait()后等待内置锁进入同步块或方法
BLOCKED,
// 在调用无参的wait(),Thread.join()或LockSupport.lock()方法后进入等待状态
WAITING,
// 调用Thread.sleep(), 有时间参数的wait(), 有时间参数的Thread.join(), LockSupport.parkNanos或LockSupport.parkUtil方法后进行有期限的等待状态
TIMED_WAITING,
// 执行完毕的线程状态
TERMINATED;
}
public State getState() {
// get current thread state
return sun.misc.VM.toThreadState(threadStatus);
}