`
wdhdmx
  • 浏览: 300427 次
  • 性别: Icon_minigender_1
  • 来自: 山西
博客专栏
D4bbb5f7-9aa4-3e66-8194-f61b3f0241c2
天天编程
浏览量:21529
社区版块
存档分类
最新评论

Thread源码理解

阅读更多

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;
	    }
	}
    }

  总结:没看懂。倒是很好奇native里面写的是什么。

分享到:
评论

相关推荐

    java8源码-jdk8:jdk8源码阅读理解

    jdk8源码的阅读理解 导入idea步骤: 阅读顺序: 大致思路 基本类型的包装类(Character放在最后) String、StringBuffer、StringBuilder、StringJoiner、StringTokenizer(补充正则表达式的知识) CharacterIterator、...

    java concurrent 精简源码

    java concurrent 阻塞队列 线程 里面有详细的例子,下载后请认真阅读里面的内容,可能有点难以理解,请耐心

    STM32F103移植RT_Thread4.0---点灯开始

    在原子哥战舰老板子上(STM32F103ZET6)上移植的RT_Thread4.0操作系统,可以作为一个demo程序,自己是验证成功可以跑起来的,分享一下源码,按照自己的理解将该工程文件分别组织在不同的文件夹中

    深入理解Android卷1全

    深入理解Android 卷1 不是扫描版的,是全版电子书的,非PDF,可编辑,各种阅览器以打开!包括书签和同步目录! 第1章 阅读前的准备工作 / 1 1.1 系统架构 / 2 1.1.1 Android系统架构 / 2 1.1.2 本书的架构 / 3 1.2 ...

    jstack生成的Thread Dump日志.docx

    如果在Thread Dump中发现这个情况,应该审视源码并对其进行改进。 (2)"Wait Set"里面的线程 当线程获得了Monitor,进入了临界区之后,如果发现线程继续运行的条件没有满足,它则调用对象(通常是被...

    深入理解Android++卷1pdf电子书

    《深入理解Android(卷1)》共10章,第1章介绍了阅读本书所需要做的准备工作,主要包括对Android系统架构和源码阅读方法的介绍;第2章通过对Android系统中的MediaScanner进行分析,详细讲解了Android中十分重要的JNI...

    深入理解Android:卷2

    深入理解Android:卷2》是一本以情景方式对Android的源代码进行深入分析的书。内容广泛,以对Framework层的分析为主,兼顾Native层和Application层;分析深入,每一部分源代码的分析都力求透彻;针对性强,注重实际...

    西南科技大学Java程序设计与实践 实验六 多线程实验实验报告及源码

    西南科技大学Java程序设计与实践 实验六 多线程实验实验报告及源码 一、实验目的:练习多线程类的两种实现方法,理解多线程程序的生命周期。 二、实验内容:编写一多线程程序,实现如下功能: (1)一个线程进行阶乘...

    java多线程机制 -- 源码详解

    java多线程机制: 例子 1 public class Example1 { static Lefthand left;static Righthand right; public static void main(String args[]) { left=new Lefthand();... else if(Thread.currentThread()==right) ...

    深入理解Android卷1

    深入理解Android:卷I》是一本以情景方式对Android的源代码进行深入分析的书。内容广泛,以对Framework层的分析为主,兼顾Native层和Application层;分析深入,每一部分源代码的分析都力求透彻;针对性强,注重实际...

    深入理解Android 卷1.pdf

    共10章,第1章介绍了阅读本书所需要做的准备工作,主要包括对Android系统架构和源码阅读方法的介绍;第2章通过对Android系统中的MediaScanner进行分析,详细讲解了Android中十分重要的JNI技术;第3章分析了init进程...

    [bugfix]重新理解Thread的InterruptedException

    NULL 博文链接:https://sw1982.iteye.com/blog/654409

    《深入理解Android:卷I》试读本

    《深入理解Android:卷I》是一本以情景方式对Android的源代码进行深入分析的书。内容广泛,以对Framework层的分析为主,兼顾Native层和Application层;分析深入,每一部分源代码的分析都力求透彻;针对性强,注重实际...

    深入理解Android:卷I--详细书签版

     第5章讲解了Android源码中常用的类,如sp、wp、RefBase、Thread类、同步类、Java中的Handler类以及Looper类。这些类都是Android中最常用和最基本的,只有掌握这些类的知识,才 能在分析后续的代码时游刃有余。 ...

    《深入理解Android》卷Ⅰ

    1.2.1 下载源码 1.2.2 编译源码 1.3 工具介绍 1.3.1 Source Insight介绍 1.3.3 Busybox的使用 1.4 本章小结 第2章 深入理解JNI 2.1 JNI概述 2.2 学习JNI的实例:MediaScanner 2.3 Java层的MediaScanner分析 2.3.1 ...

    深入理解Android 卷I

    第5章讲解了android系统中常用的类,包括sp、wp、refbase、thread等类,同步类,以及java中的handler类和looper类,掌握这些类的知识后方能在后续的代码分析中做到游刃有余;第6章以mediaserver为切入点,对android...

    worldwindjava源码-Thread-Count:并行+并发编程的旧笔记

    世界风java源码内容 介绍和概述 本文档试图绘制出我自己对理解并发和并行编程的深入了解。 这份文件将是一个不断的工作和进步。 很多东西要学。 很多东西要覆盖。 我为什么要写这个? 我通过学习 Javascript 开始...

    QQ客户端全源码(使用腾讯W.QQ协议)

    【版权】 Author:NinJa911 ...本贴转自: http://www.aau.cn/thread-4216-1-1.html ...“自由”请理解好,请不要拿这个东西干坏事,切忌切忌! 2、可以转载,可以二次开发,可以商用,反正“自由”。

Global site tag (gtag.js) - Google Analytics