1.首先看一下Runnable接口,只有一个run方法。
Thread方法继承Runnable接口。
package java.lang;
public interface Runnable {
public abstract void run();
}
2.看一下Thread实现的run()方法。
//target 为传入线程的对象
private Runnable target;
public void run() {
if (target != null) {
target.run();
}
}
//这个就是target的来源。
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
3.构造函数
在构造函数之前,Thread类中还有一个静态的代码块,这个是Object的方法,这里应该是重写了。
private static native void registerNatives();
static {
registerNatives();
}
private void init(ThreadGroup g, Runnable target, String name, long stackSize) {
//返回当前执行的线程。
Thread parent = currentThread();
//安全管理,查看线程拥有的功能(例如:读写文件,访问网络)。
SecurityManager security = System.getSecurityManager();
//g这个变量是线程组
if (g == null) {
if (security != null) {
g = security.getThreadGroup();
}
if (g == null) {
g = parent.getThreadGroup();
}
}
//确定当前运行的线程是否有权修改此线程组。
g.checkAccess();
if (security != null) {
//这个好像是验证是不是子类
if (isCCLOverridden(getClass())) {
//检查什么权限
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
//记录一个线程到线程组里,好像只是取得一个线程号。
g.addUnstarted();
this.group = g;
//线程是否为守护线程
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);
//栈的大小
this.stackSize = stackSize;
//线程id,并且+1
tid = nextThreadID();
}
4.线程的名字相关方法
//存线程的名字的数组,这里面没用String。看来char[]的效率会高一点.
private char name[];
//线程的编号,没有赋初值,所以从0开始。静态的。
private static int threadInitNumber;
public final String getName() {
return String.valueOf(name);
}
public final void setName(String name) {
//判定当前运行的线程是否有权修改该线程.(意思好像是主线程能不能修改当前线程??)
checkAccess();
this.name = name.toCharArray();
}
//判定当前运行的线程是否有权修改该线程.
public final void checkAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkAccess(this);
}
}
//这个是初始化线程的操作,名字默认Thread-0 Thread-1
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
//带参的构造函数,只是给线程起了个名字。
public Thread(String name) {
init(null, null, name, 0);
}
//同步获取线程编号,并+1
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
还有在线程运行的时候还能改线程名字,并且各个线程的名字可以一样,用线程组管理的。
5.start方法。
//线程状态
private int threadStatus = 0;
//线程自己停止,还是用stop()停止线程的。默认值为false;
private boolean stopBeforeStart;
public synchronized void start() {
//重复start()会报错
if (threadStatus != 0)
throw new IllegalThreadStateException();
//线程组添加这个线程。
group.add(this);
start0();
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
private native void start0();
private native void stop0(Object o);
几个等待的操作
6.yield(),释放
暂停当前正在执行的线程对象,并执行其他线程。只是暂停一下。
public static native void yield();
7.sleep() 睡
public static native void sleep(long millis) throws InterruptedException;
sleep,很无耻的一个,纳秒功能形同虚设。
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");
}
//就是纳秒大于500000 ,即大于0.5毫秒的时候四舍五入。或者毫秒为0、纳秒不为0时,睡一微秒。
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
sleep(millis);
}
8.interrupt()
中断线程。
private Object blockerLock = new Object();
void blockedOn(Interruptible b) {
synchronized (blockerLock) {
blocker = b;
}
}
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // 只改一个flag?
b.interrupt();
return;
}
}
interrupt0();
}
private native void interrupt0();
使用起来很简单,直接使用t.interrupt(),即停止,但是如果停止时线程内部抛出异常的时候,线程内部还要进行一次this.interrupt()
9.Object中的notify()和wait()
等待。
public final void wait() throws InterruptedException {
wait(0);
}
public final native void wait(long timeout) throws InterruptedException;
唤醒在此对象监视器上等待的单个线程
public final native void notify();
public final native void notifyAll();
源码没有什么价值。都是native方法。
sleep()使当前线程进入停滞状态,停止固定时间,然后等待运行。
yield()只是使当前线程停一下,重新等待运行
wait()后,线程会释放掉它所占有的“锁标志”, 对应notify。
10.stop
//线程状态,0标识未启动。
private int threadStatus = 0;
@Deprecated
public final synchronized void stop(Throwable obj) {
stop1(obj);
}
private final synchronized void stop1(Throwable th) {
//获得当前线程
SecurityManager security = System.getSecurityManager();
if (security != null) {
//检查权限
checkAccess();
if ((this != Thread.currentThread()) ||
(!(th instanceof ThreadDeath))) {
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
if (threadStatus != 0) {
//挂起线程
resume();
stop0(th);
} else {
if (th == null) {
throw new NullPointerException();
}
//设置为手动关闭状态。非自己运行完。
stopBeforeStart = true;
//异常对象。不知道是干什么的。
throwableFromStop = th;
}
}
private native void stop0(Object o);
11.isAlive()
又是一个native方法。
public final native boolean isAlive();
12.优先级有关方法
//最小权限
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);
}
}
public final int getPriority() {
return priority;
}
private native void setPriority0(int newPriority);
//toString方法中有优先级的输出。
13.join()
//等待线程终止,
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);
now = System.currentTimeMillis() - base;
}
}
}