`

源码分析(五)——Thread(基于JDK1.6)

 
阅读更多

一、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方法什么也不干。
 3. exit:由系统来调用该方法,在线程退出之前清理分配的资源。 
	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);
	}
 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    jdk1.6 源码jdk1.6 源码

    4. **多线程**:JDK 1.6支持多线程编程,源码中包括了`Thread`类和`synchronized`关键字的实现,以及线程同步机制如`wait()`, `notify()`, `notifyAll()`。 5. **I/O流**:在`java.io`包中,你可以看到文件读写、...

    苹果电脑安装jdk1.6 mac for jdk1.6 jdk6 安装版

    mac for jdk1.6 jdk6 安装版 里面有两个jdk1.6的安装包,都可以用 如果电脑上安装有1.7,1.8等高版本jdk就不要再下安装包了,安装包安装会报错 命令是这个:brew install java6或 brew install homebrew/cask-...

    okhttp3.8源码使用jdk1.6重新编译_okhttp3.8.0-jdk1.6.zip

    1.okhttp3.8源码使用jdk1.6重新编译,已集成了okio,在javaweb项目中使用,未在安卓项目中使用 2.okhttp3.8源码使用jdk1.6重新编译_okhttp3.8.0-jdk1.6.jar

    jdk1.6集成jjwt的问题

    标题中的“jdk1.6集成jjwt的问题”指的是在Java Development Kit (JDK) 版本1.6的环境下,尝试整合JSON Web Token (JWT) 库jjwt时遇到的挑战。JWT是一种开放标准(RFC 7519),用于在各方之间安全地传输信息作为 ...

    PostgreSQL JDBC 驱动包,最新的基于 jdk 1.6 的 jdbc 驱动包

    PostgreSQL JDBC 驱动包,最新的基于 jdk 1.6 的 jdbc 驱动包

    aspose-words-15.8.0-jdk1.6

    aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-...

    JDK1.6版本下载

    **JDK 1.6版本详解** Java Development Kit(JDK)是Oracle公司提供的用于开发和运行Java应用程序的工具集合。JDK 1.6,也被称为Java SE 6,是Java平台的一个重要版本,发布于2006年12月11日。这个版本在Java社区中...

    JDK1.6百度云下载

    根据提供的标题、描述以及部分内容,我们可以总结出与JDK1.6百度云下载相关的几个重要知识点: ### 一、JDK1.6简介 Java Development Kit(简称JDK)是Sun Microsystems公司针对Java语言开发的一套开发工具包,它...

    jdk1.6 解压版-windows

    JDK1.6是Oracle公司发布的一个较早版本,适用于Windows操作系统。在这个解压版中,用户无需进行安装过程,可以直接在Windows环境下使用JDK的各个工具。 JDK1.6包含的主要组件有: 1. **Java编译器**(javac):...

    jdk1.6压缩包,下载即用

    - **下载**:从Oracle官网或其他可信源下载JDK 1.6的安装文件,如"jdk1.6.exe"。 - **安装**:双击执行安装文件,按照向导步骤进行安装,选择合适的安装路径。 - **环境变量设置**:安装完成后,需要在系统环境变量...

    zxing jar包,支持jdk1.6,包括源码

    - 这可能是ZXing库的完整源码包,专门针对JDK1.6编译,包含了所有必要的源文件和资源,供开发者进行更深度的定制和集成。 总之,ZXing库是一个强大的条形码和二维码工具,这个特别适配JDK1.6的版本为那些仍在使用...

    jdk1.6源代码

    JDK 1.6,又称为JDK 6,是Java开发工具包的一个重要版本,由Sun Microsystems(后被Oracle收购)在2006年发布。这个版本引入了许多新特性,优化和改进,旨在提升开发者体验和应用程序性能。源代码的提供对于学习Java...

    jdk1.6jar包

    **Java Development Kit (JDK) 1.6详解** Java Development Kit (JDK) 是Java编程语言的核心组件,用于开发和运行Java应用程序。JDK 1.6是Oracle公司发布的一个重要版本,它包含了编译器、Java虚拟机(JVM)、类库...

    okhttp3.8.0-jdk1.6.zip

    《OkHttp3.8.0-JDK1.6:低版本环境下的高效网络通信库》 OkHttp3.8.0-jdk1.6.zip是一个专门为Java Web项目设计的网络通信库,它针对JDK1.6进行了优化和重新编译,确保在较低版本的Java环境中也能稳定运行。OkHttp,...

    jdk1.6 32位免安装纯绿色版

    本资源是JDK 1.6的32位免安装纯绿色版本,非常适合那些希望快速启动Java开发而无需进行复杂安装过程的用户。 JDK 1.6,也被称为Java SE 6,是Sun Microsystems(后被Oracle公司收购)发布的Java平台标准版的一个...

    jdk 1.6 64位

    JDK 1.6,也称为Java SE(标准版)6,是Java编程语言的一个早期版本,发布于2006年。它包含了Java编译器、Java虚拟机(JVM)、Java类库以及开发者用来创建、调试和部署Java应用程序所需的各种工具。 **JDK 1.6的...

    jdk1.6解压版(免安装版)

    在给定的"jdk1.6解压版(免安装版)"中,用户无需经历传统意义上的安装过程,只需将压缩包解压到指定位置,然后配置系统环境变量,就可以开始使用这个版本的JDK进行Java程序的开发和运行。 1. **JDK1.6**:这是Java的...

    jdk1.5 jdk1.6 反编译 工具

    标题中的“jdk1.5 jdk1.6 反编译 工具”指的是用于对Java字节码进行反编译的软件,这类工具能够将Java的.class文件转换回可读的.java源代码形式,这对于理解和学习已有的Java类库或者进行逆向工程非常有帮助。...

    IBMJDK1.6linux.zip

    IBM JDK 1.6是IBM公司为Java开发者提供的一个针对Linux 64位操作系统的Java开发工具包。这个版本的JDK是Java平台标准版(Java SE)的一部分,主要用于开发和运行Java应用程序、Web应用程序以及企业级应用。IBM JDK与...

    解决JDK1.6下的Base64报错问题

    在资源文件中的`解决JDK1.6下的Base64.jar`可能是包含了一个兼容JDK 1.6的Base64实现的第三方库,你可以直接将这个jar包添加到你的项目类路径中,这样就可以使用其中提供的Base64类而无需修改代码。添加方法通常包括...

Global site tag (gtag.js) - Google Analytics