1.概述
Java所有多线程的实现,均通过封装Thread类实现
2.类图
实现了Runnable接口
Runnable的源码非常简单,只有一个抽象方法。@FunctionalInterface是jdk1.8出现的函数式接口。用于Lamda表达式。
可以把Runnable看作是一个任务,run方法就是任务要完成的事情
3.属性
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;//JVM状态
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;//线程ID
private static long threadSeqNumber;//用于生成线程ID
private volatile int threadStatus = 0;//线程的状态
volatile Object parkBlocker;//
private volatile Interruptible blocker;//在可中断的I / O操作中阻塞该线程的对象(如果有)。设置此线程的中断状态后,应调用阻塞程序的中断方法
public final static int MIN_PRIORITY = 1;//线程最低优先级
public final static int NORM_PRIORITY = 5;//线程默认优先级
public final static int MAX_PRIORITY = 10;//线程最高优先级
4.构造方法
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
Thread(Runnable target, AccessControlContext acc) {
init(null, target, "Thread-" + nextThreadNum(), 0, acc);
}
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);
}
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
public Thread(ThreadGroup group, Runnable target, String name,
long stackSize) {
init(group, target, name, stackSize);
}
上述构造方法都调用了init来实现 init是一个private方法只有Thread内部自己使用
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null);
}
//参数分别表示 线程组,任务,线程名字,堆栈大小,此线程的继承的访问控制上下文
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name.toCharArray();//设置线程的名字
Thread parent = currentThread();//获取当前执行的线程
SecurityManager security = System.getSecurityManager();//获取安全管理器
if (g == null) {//线程组为空
if (security != null) {//若安全管理器不为空
g = security.getThreadGroup();//用安全管理器来获取线程组
}
if (g == null) {//若为空
g = parent.getThreadGroup();//则使用parent来获取线程组。
}
}
g.checkAccess();
/*
* Do we have the required permissions?
检查是否有权限
*/
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
g.addUnstarted();//增加线程组中未启动的线程的数量。
this.group = g;//设置线程组
this.daemon = parent.isDaemon();//当前线程的守护线程标记等于parent线程的守护线程标记。说明父线程是守护线程的话,子线程也必须是守护线程
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 (parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
tid = nextThreadID();//线程id
}
5.本地方法
public static native Thread currentThread();//获取当前线程
public static native void yield();//给调度程序的提示是当前线程愿意放弃对处理器的当前使用。
public static native void sleep(long millis)//使线程休眠一定时间,不释放锁
private native void start0()//启动线程
private native boolean isInterrupted(boolean ClearInterrupted);//是否被中断,根据传入的参数,来重置或者不重置中断标记
public final native boolean isAlive();//当前线程是否存活
@Deprecated
public native int countStackFrames();//统计栈帧数量
public static native boolean holdsLock(Object obj);//是否持有锁
private native static StackTraceElement[][] dumpThreads(Thread[] threads);
private native static Thread[] getThreads();
private native void setPriority0(int newPriority);//设置线程优先级
private native void stop0(Object o);//停止线程
private native void suspend0();//挂起线程
private native void resume0();//恢复挂起的线程
private native void interrupt0();//设置中断标记
private native void setNativeName(String name);//设置名字
6.常用方法
-
sleep(long millis, int nanos)
纳秒的作用仅仅只是在millis的基础上加一毫秒。
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)) {
millis++;
}
sleep(millis);
}
- start()
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);//将该线程添加到线程组中
boolean started = false;
try {
start0();//真正的执行启动线程是由本地方法来实现的
started = true;//启动成功将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 */
}
}
}
void threadStartFailed(Thread t) {
synchronized(this) {
remove(t);
nUnstartedThreads++;
}
}
-
run
去实现了runnable接口中的run方法
public void run() {
if (target != null) {
target.run();
}
}
-
exit
用于退出线程前清空成员变量。以及线程组中移除该线程。
private void exit() {
if (group != null) {
group.threadTerminated(this);
group = null;
}
/* Aggressively null out all reference fields: see bug 4006245 */
target = null;
/* Speed the release of some of these resources */
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
- 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(this);
return;
}
}
interrupt0();
}
public static boolean interrupted() {//判断是否处于中断,并重置中断标记
return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {//判断是否处于中断,不重置中断标记
return isInterrupted(false);
}
- setPriority(int newPriority) 设置优先级
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);
}
}
- join 其实内部调用的是Object的wait方法
public final void join() throws InterruptedException {
join(0);//一直等待
}
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) {
while (isAlive()) {
wait(0);//若线程存活则一直等待
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {//超过等待时间,则结束等待
break;
}
wait(delay);//若线程存活等待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)) {
millis++;
}
join(millis);
}
- setDaemon(boolean on) 设置守护线程标识
public final void setDaemon(boolean on) {
checkAccess();
if (isAlive()) {
throw new IllegalThreadStateException();
}
daemon = on;
}
7.线程状态
java中线程的状态有6种
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
}
刚创建的线程 还没有start之前的状态是NEW
就绪状态(可运行线程的线程状态。 处于可运行状态的线程正在Java虚拟机中执行,但它可能正在等待来自操作系统(例如处理器)的其他资源)的线程是RUNNABLE
没有获得临界资源被阻塞的线程是BLOCKED
无限期等待状态 调用了Object.wait,Thread.join,LockSupport.park的线程是WAITING
有限等待状态 调用了Thread.sleep Object.wait带参数 Thread.join带参数 LockSupport.parkNanos LockSupport.parkUntil 的线程是TIMED_WAITING
终止了的线程是TERMINATED