多线程编程(二)-----多线程的实现

本文介绍了Java中实现多线程的多种方法,包括继承Thread类、实现Runnable接口及Callable接口等。并通过示例代码展示了如何创建和启动线程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、多线程的实现方式

            由于线程是依赖进程而存在的,我们首先应该创建一个进程出来。而进程是由系统创建的,所以我们应该去调用系统功能创建一个进程。Java是不能直接调用系统功能的,多以我呢吧没有办法直接实现多线程程序。但是java 可以去调用C/C++写好的程序来实现多线程程序,由CC++去调用系统功能创建进程,然后由Java去调用这样的东西,然后提供一些类或接口给我们使用,我们就可以实现多线程程序了。

        多线程实现方式主要有四种:继承Thread类、实现Runnable接口、实现Callable接口通过FutureTask包装器来创建Thread线程、使用ExecutorService、Callable、Future实现有返回结果的多线程。

1.1 继承java.lang.Thread类

 1):继承Thread类定义线程子类;

 2):重写run()方法,定义线程的操作;

3):通过创建的线程子类对象.start() 启动线程

package cn.itcast_02;
/*
 * 该类要重写run()方法,为什么呢?
 * 不是类中的所有代码都需要被线程执行的。
 * 而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码。
 */
public class MyThread_01 extends Thread {
	@Override
	public void run() {
		// 一般来说,被线程执行的代码肯定是比较耗时的。所以我们用循环改进模拟
		for (int x = 0; x < 200; x++) {
			System.out.println(Thread.currentThread().getName()+"==="+x);
		}
	}
}

测试类:

package cn.itcast_02.test;

import cn.itcast_02.MyThread_01;

public class MyThread_01Test {

	public static void main(String[] args) {
		MyThread_01 m1=new  MyThread_01();
		m1.start();
	}

}

测试结果:

Thread-0===0
Thread-0===1
Thread-0===2
Thread-0===3
Thread-0===4
Thread-0===5
Thread-0===6
Thread-0===7
Thread-0===8
Thread-0===9
Thread-0===10
Thread-0===11
Thread-0===12
Thread-0===13
Thread-0===14
Thread-0===15
Thread-0===16
Thread-0===17
Thread-0===18
Thread-0===19
Thread-0===20
Thread-0===21
Thread-0===22
Thread-0===23
Thread-0===24
Thread-0===25
Thread-0===26
Thread-0===27
Thread-0===28
Thread-0===29
Thread-0===30
Thread-0===31
Thread-0===32
Thread-0===33
Thread-0===34
Thread-0===35
Thread-0===36
Thread-0===37
Thread-0===38
Thread-0===39
Thread-0===40
Thread-0===41
Thread-0===42
Thread-0===43
Thread-0===44
Thread-0===45
Thread-0===46
Thread-0===47
Thread-0===48
Thread-0===49
Thread-0===50
Thread-0===51
Thread-0===52
Thread-0===53
Thread-0===54
Thread-0===55
Thread-0===56
Thread-0===57
Thread-0===58
Thread-0===59
Thread-0===60
Thread-0===61
Thread-0===62
Thread-0===63
Thread-0===64
Thread-0===65
Thread-0===66
Thread-0===67
Thread-0===68
Thread-0===69
Thread-0===70
Thread-0===71
Thread-0===72
Thread-0===73
Thread-0===74
Thread-0===75
Thread-0===76
Thread-0===77
Thread-0===78
Thread-0===79
Thread-0===80
Thread-0===81
Thread-0===82
Thread-0===83
Thread-0===84
Thread-0===85
Thread-0===86
Thread-0===87
Thread-0===88
Thread-0===89
Thread-0===90
Thread-0===91
Thread-0===92
Thread-0===93
Thread-0===94
Thread-0===95
Thread-0===96
Thread-0===97
Thread-0===98
Thread-0===99
Thread-0===100
Thread-0===101
Thread-0===102
Thread-0===103
Thread-0===104
Thread-0===105
Thread-0===106
Thread-0===107
Thread-0===108
Thread-0===109
Thread-0===110
Thread-0===111
Thread-0===112
Thread-0===113
Thread-0===114
Thread-0===115
Thread-0===116
Thread-0===117
Thread-0===118
Thread-0===119
Thread-0===120
Thread-0===121
Thread-0===122
Thread-0===123
Thread-0===124
Thread-0===125
Thread-0===126
Thread-0===127
Thread-0===128
Thread-0===129
Thread-0===130
Thread-0===131
Thread-0===132
Thread-0===133
Thread-0===134
Thread-0===135
Thread-0===136
Thread-0===137
Thread-0===138
Thread-0===139
Thread-0===140
Thread-0===141
Thread-0===142
Thread-0===143
Thread-0===144
Thread-0===145
Thread-0===146
Thread-0===147
Thread-0===148
Thread-0===149
Thread-0===150
Thread-0===151
Thread-0===152
Thread-0===153
Thread-0===154
Thread-0===155
Thread-0===156
Thread-0===157
Thread-0===158
Thread-0===159
Thread-0===160
Thread-0===161
Thread-0===162
Thread-0===163
Thread-0===164
Thread-0===165
Thread-0===166
Thread-0===167
Thread-0===168
Thread-0===169
Thread-0===170
Thread-0===171
Thread-0===172
Thread-0===173
Thread-0===174
Thread-0===175
Thread-0===176
Thread-0===177
Thread-0===178
Thread-0===179
Thread-0===180
Thread-0===181
Thread-0===182
Thread-0===183
Thread-0===184
Thread-0===185
Thread-0===186
Thread-0===187
Thread-0===188
Thread-0===189
Thread-0===190
Thread-0===191
Thread-0===192
Thread-0===193
Thread-0===194
Thread-0===195
Thread-0===196
Thread-0===197
Thread-0===198
Thread-0===199

1.2 实现java.lang.Runnable接口

       A:自定义类MyRunnable实现Runnable接口
       B:重写run()方法
       C:创建MyRunnable类 的对象
       D:创建Thread类的对象,并把C步骤对象作为构造参数传递


package cn.itcast_02;

public class MyThread_02 implements Runnable {

	@Override
	public void run() {
		// 一般来说,被线程执行的代码肯定是比较耗时的。所以我们用循环改进模拟
		for (int x = 0; x < 200; x++) {
			System.out.println(Thread.currentThread().getName()+"==="+x);
		}
	}

}

测试类:

package cn.itcast_02.test;

import cn.itcast_02.MyThread_02;

public class MyThread_02Test {

	public static void main(String[] args) {
		
		////创建MyRunnable类的对象
		MyThread_02 t_02=new MyThread_02(); 

		Thread t=new Thread(t_02,"花狐貂");
		t.start();
	}

}

运行结果:

花狐貂===0
花狐貂===1
花狐貂===2
花狐貂===3
花狐貂===4
花狐貂===5
花狐貂===6
花狐貂===7
花狐貂===8
花狐貂===9
花狐貂===10
花狐貂===11
花狐貂===12
花狐貂===13
花狐貂===14
花狐貂===15
花狐貂===16
花狐貂===17
花狐貂===18
花狐貂===19
花狐貂===20
花狐貂===21
花狐貂===22
花狐貂===23
花狐貂===24
花狐貂===25
花狐貂===26
花狐貂===27
花狐貂===28
花狐貂===29
花狐貂===30
花狐貂===31
花狐貂===32
花狐貂===33
花狐貂===34
花狐貂===35
花狐貂===36
花狐貂===37
花狐貂===38
花狐貂===39
花狐貂===40
花狐貂===41
花狐貂===42
花狐貂===43
花狐貂===44
花狐貂===45
花狐貂===46
花狐貂===47
花狐貂===48
花狐貂===49
花狐貂===50
花狐貂===51
花狐貂===52
花狐貂===53
花狐貂===54
花狐貂===55
花狐貂===56
花狐貂===57
花狐貂===58
花狐貂===59
花狐貂===60
花狐貂===61
花狐貂===62
花狐貂===63
花狐貂===64
花狐貂===65
花狐貂===66
花狐貂===67
花狐貂===68
花狐貂===69
花狐貂===70
花狐貂===71
花狐貂===72
花狐貂===73
花狐貂===74
花狐貂===75
花狐貂===76
花狐貂===77
花狐貂===78
花狐貂===79
花狐貂===80
花狐貂===81
花狐貂===82
花狐貂===83
花狐貂===84
花狐貂===85
花狐貂===86
花狐貂===87
花狐貂===88
花狐貂===89
花狐貂===90
花狐貂===91
花狐貂===92
花狐貂===93
花狐貂===94
花狐貂===95
花狐貂===96
花狐貂===97
花狐貂===98
花狐貂===99
花狐貂===100
花狐貂===101
花狐貂===102
花狐貂===103
花狐貂===104
花狐貂===105
花狐貂===106
花狐貂===107
花狐貂===108
花狐貂===109
花狐貂===110
花狐貂===111
花狐貂===112
花狐貂===113
花狐貂===114
花狐貂===115
花狐貂===116
花狐貂===117
花狐貂===118
花狐貂===119
花狐貂===120
花狐貂===121
花狐貂===122
花狐貂===123
花狐貂===124
花狐貂===125
花狐貂===126
花狐貂===127
花狐貂===128
花狐貂===129
花狐貂===130
花狐貂===131
花狐貂===132
花狐貂===133
花狐貂===134
花狐貂===135
花狐貂===136
花狐貂===137
花狐貂===138
花狐貂===139
花狐貂===140
花狐貂===141
花狐貂===142
花狐貂===143
花狐貂===144
花狐貂===145
花狐貂===146
花狐貂===147
花狐貂===148
花狐貂===149
花狐貂===150
花狐貂===151
花狐貂===152
花狐貂===153
花狐貂===154
花狐貂===155
花狐貂===156
花狐貂===157
花狐貂===158
花狐貂===159
花狐貂===160
花狐貂===161
花狐貂===162
花狐貂===163
花狐貂===164
花狐貂===165
花狐貂===166
花狐貂===167
花狐貂===168
花狐貂===169
花狐貂===170
花狐貂===171
花狐貂===172
花狐貂===173
花狐貂===174
花狐貂===175
花狐貂===176
花狐貂===177
花狐貂===178
花狐貂===179
花狐貂===180
花狐貂===181
花狐貂===182
花狐貂===183
花狐貂===184
花狐貂===185
花狐貂===186
花狐貂===187
花狐貂===188
花狐貂===189
花狐貂===190
花狐貂===191
花狐貂===192
花狐貂===193
花狐貂===194
花狐貂===195
花狐貂===196
花狐貂===197
花狐貂===198
花狐貂===199

1.3 实现Callable接口

1)创建一个类实现Callable接口,实现call方法。这个接口类似于Runnable接口,但比Runnable接口更加强大,增加了异常和返回值

2)创建一个FutureTask,指定Callable对象,做为线程任务。

3)创建线程,指定线程任务。

4)启动线程

使用ExecutorService、Callable、Future实现有返回结果的线程

package cn.itcast_02;

import java.util.concurrent.Callable;

public class MyThread_03 implements Callable<String> {

	@Override
	 //重写call()方法,切记抛出异常,并返回值
	public String call() throws Exception {
		long start = System.currentTimeMillis(); // 记录起始时间
		// 一般来说,被线程执行的代码肯定是比较耗时的。所以我们用循环改进模拟
		for (int x = 0; x < 200; x++) {
			System.out.println(Thread.currentThread().getName()+"==="+x);
			
		}
		long end =System.currentTimeMillis();
		return Thread.currentThread().getName()+"==="+(end-start);
	}

}
测试类:
package cn.itcast_02.test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import cn.itcast_02.MyThread_03;

public class MyThread_03Test {

	public static void main(String[] args) {

		// 创建线程池
		ExecutorService es = Executors.newCachedThreadPool();
		// 创建预期结果集合
		List<Future<String>> results = new ArrayList<Future<String>>();

		for (int i = 0; i < 5; i++) {
			// 通过线程池启动线程,把线程结果保存到预期结果集合
			results.add(es.submit(new MyThread_03()));
		}

		// 遍历结果集合
		for (Future<String> fs : results) {

			// 通过 结果.get() 方法获取每个线程运行结束后的返回值。并处理异常
			try {
				System.out.println(fs.get());
			} catch (InterruptedException | ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
		//线程池使用完毕后关闭线程池
		es.shutdown();
	}

}

运行结果:
pool-1-thread-1===0
pool-1-thread-1===1
pool-1-thread-2===0
pool-1-thread-3===0
pool-1-thread-3===1
pool-1-thread-3===2
pool-1-thread-3===3
pool-1-thread-3===4
pool-1-thread-3===5
pool-1-thread-3===6
pool-1-thread-3===7
pool-1-thread-3===8
pool-1-thread-3===9
pool-1-thread-3===10
pool-1-thread-3===11
pool-1-thread-3===12
pool-1-thread-3===13
pool-1-thread-3===14
pool-1-thread-3===15
pool-1-thread-3===16
pool-1-thread-3===17
pool-1-thread-3===18
pool-1-thread-3===19
pool-1-thread-3===20
pool-1-thread-3===21
pool-1-thread-3===22
pool-1-thread-3===23
pool-1-thread-3===24
pool-1-thread-3===25
pool-1-thread-3===26
pool-1-thread-3===27
pool-1-thread-3===28
pool-1-thread-3===29
pool-1-thread-3===30
pool-1-thread-3===31
pool-1-thread-3===32
pool-1-thread-3===33
pool-1-thread-3===34
pool-1-thread-3===35
pool-1-thread-3===36
pool-1-thread-3===37
pool-1-thread-3===38
pool-1-thread-3===39
pool-1-thread-3===40
pool-1-thread-3===41
pool-1-thread-3===42
pool-1-thread-3===43
pool-1-thread-3===44
pool-1-thread-3===45
pool-1-thread-3===46
pool-1-thread-3===47
pool-1-thread-3===48
pool-1-thread-3===49
pool-1-thread-3===50
pool-1-thread-3===51
pool-1-thread-3===52
pool-1-thread-3===53
pool-1-thread-3===54
pool-1-thread-3===55
pool-1-thread-3===56
pool-1-thread-3===57
pool-1-thread-3===58
pool-1-thread-3===59
pool-1-thread-3===60
pool-1-thread-3===61
pool-1-thread-3===62
pool-1-thread-3===63
pool-1-thread-3===64
pool-1-thread-3===65
pool-1-thread-3===66
pool-1-thread-3===67
pool-1-thread-3===68
pool-1-thread-3===69
pool-1-thread-3===70
pool-1-thread-3===71
pool-1-thread-3===72
pool-1-thread-3===73
pool-1-thread-3===74
pool-1-thread-3===75
pool-1-thread-3===76
pool-1-thread-3===77
pool-1-thread-3===78
pool-1-thread-3===79
pool-1-thread-3===80
pool-1-thread-3===81
pool-1-thread-3===82
pool-1-thread-3===83
pool-1-thread-3===84
pool-1-thread-3===85
pool-1-thread-3===86
pool-1-thread-3===87
pool-1-thread-3===88
pool-1-thread-3===89
pool-1-thread-3===90
pool-1-thread-3===91
pool-1-thread-3===92
pool-1-thread-3===93
pool-1-thread-3===94
pool-1-thread-3===95
pool-1-thread-3===96
pool-1-thread-3===97
pool-1-thread-3===98
pool-1-thread-3===99
pool-1-thread-3===100
pool-1-thread-3===101
pool-1-thread-3===102
pool-1-thread-3===103
pool-1-thread-3===104
pool-1-thread-3===105
pool-1-thread-3===106
pool-1-thread-3===107
pool-1-thread-3===108
pool-1-thread-3===109
pool-1-thread-3===110
pool-1-thread-3===111
pool-1-thread-3===112
pool-1-thread-3===113
pool-1-thread-3===114
pool-1-thread-3===115
pool-1-thread-3===116
pool-1-thread-3===117
pool-1-thread-3===118
pool-1-thread-3===119
pool-1-thread-3===120
pool-1-thread-3===121
pool-1-thread-3===122
pool-1-thread-3===123
pool-1-thread-3===124
pool-1-thread-3===125
pool-1-thread-3===126
pool-1-thread-3===127
pool-1-thread-3===128
pool-1-thread-3===129
pool-1-thread-3===130
pool-1-thread-3===131
pool-1-thread-3===132
pool-1-thread-3===133
pool-1-thread-3===134
pool-1-thread-3===135
pool-1-thread-3===136
pool-1-thread-3===137
pool-1-thread-3===138
pool-1-thread-3===139
pool-1-thread-3===140
pool-1-thread-3===141
pool-1-thread-3===142
pool-1-thread-3===143
pool-1-thread-3===144
pool-1-thread-3===145
pool-1-thread-3===146
pool-1-thread-3===147
pool-1-thread-3===148
pool-1-thread-3===149
pool-1-thread-3===150
pool-1-thread-3===151
pool-1-thread-3===152
pool-1-thread-3===153
pool-1-thread-3===154
pool-1-thread-3===155
pool-1-thread-3===156
pool-1-thread-3===157
pool-1-thread-3===158
pool-1-thread-3===159
pool-1-thread-3===160
pool-1-thread-3===161
pool-1-thread-3===162
pool-1-thread-3===163
pool-1-thread-3===164
pool-1-thread-3===165
pool-1-thread-3===166
pool-1-thread-3===167
pool-1-thread-3===168
pool-1-thread-3===169
pool-1-thread-3===170
pool-1-thread-3===171
pool-1-thread-3===172
pool-1-thread-3===173
pool-1-thread-3===174
pool-1-thread-3===175
pool-1-thread-3===176
pool-1-thread-3===177
pool-1-thread-3===178
pool-1-thread-3===179
pool-1-thread-3===180
pool-1-thread-3===181
pool-1-thread-3===182
pool-1-thread-3===183
pool-1-thread-3===184
pool-1-thread-3===185
pool-1-thread-3===186
pool-1-thread-3===187
pool-1-thread-3===188
pool-1-thread-3===189
pool-1-thread-3===190
pool-1-thread-3===191
pool-1-thread-3===192
pool-1-thread-3===193
pool-1-thread-3===194
pool-1-thread-3===195
pool-1-thread-3===196
pool-1-thread-3===197
pool-1-thread-3===198
pool-1-thread-3===199
pool-1-thread-1===2
pool-1-thread-5===0
pool-1-thread-5===1
pool-1-thread-5===2
pool-1-thread-5===3
pool-1-thread-5===4
pool-1-thread-5===5
pool-1-thread-5===6
pool-1-thread-5===7
pool-1-thread-5===8
pool-1-thread-5===9
pool-1-thread-5===10
pool-1-thread-5===11
pool-1-thread-5===12
pool-1-thread-5===13
pool-1-thread-5===14
pool-1-thread-5===15
pool-1-thread-5===16
pool-1-thread-5===17
pool-1-thread-5===18
pool-1-thread-5===19
pool-1-thread-5===20
pool-1-thread-5===21
pool-1-thread-5===22
pool-1-thread-5===23
pool-1-thread-5===24
pool-1-thread-5===25
pool-1-thread-5===26
pool-1-thread-5===27
pool-1-thread-5===28
pool-1-thread-5===29
pool-1-thread-5===30
pool-1-thread-5===31
pool-1-thread-5===32
pool-1-thread-5===33
pool-1-thread-5===34
pool-1-thread-5===35
pool-1-thread-5===36
pool-1-thread-5===37
pool-1-thread-5===38
pool-1-thread-5===39
pool-1-thread-5===40
pool-1-thread-5===41
pool-1-thread-5===42
pool-1-thread-5===43
pool-1-thread-5===44
pool-1-thread-5===45
pool-1-thread-5===46
pool-1-thread-5===47
pool-1-thread-5===48
pool-1-thread-5===49
pool-1-thread-5===50
pool-1-thread-5===51
pool-1-thread-5===52
pool-1-thread-5===53
pool-1-thread-5===54
pool-1-thread-5===55
pool-1-thread-5===56
pool-1-thread-5===57
pool-1-thread-5===58
pool-1-thread-5===59
pool-1-thread-5===60
pool-1-thread-5===61
pool-1-thread-5===62
pool-1-thread-5===63
pool-1-thread-5===64
pool-1-thread-5===65
pool-1-thread-5===66
pool-1-thread-5===67
pool-1-thread-5===68
pool-1-thread-5===69
pool-1-thread-5===70
pool-1-thread-5===71
pool-1-thread-5===72
pool-1-thread-5===73
pool-1-thread-5===74
pool-1-thread-5===75
pool-1-thread-5===76
pool-1-thread-5===77
pool-1-thread-5===78
pool-1-thread-5===79
pool-1-thread-5===80
pool-1-thread-5===81
pool-1-thread-5===82
pool-1-thread-5===83
pool-1-thread-5===84
pool-1-thread-5===85
pool-1-thread-5===86
pool-1-thread-5===87
pool-1-thread-5===88
pool-1-thread-5===89
pool-1-thread-5===90
pool-1-thread-5===91
pool-1-thread-5===92
pool-1-thread-5===93
pool-1-thread-5===94
pool-1-thread-5===95
pool-1-thread-5===96
pool-1-thread-5===97
pool-1-thread-5===98
pool-1-thread-5===99
pool-1-thread-5===100
pool-1-thread-5===101
pool-1-thread-5===102
pool-1-thread-5===103
pool-1-thread-5===104
pool-1-thread-5===105
pool-1-thread-5===106
pool-1-thread-5===107
pool-1-thread-5===108
pool-1-thread-5===109
pool-1-thread-5===110
pool-1-thread-5===111
pool-1-thread-5===112
pool-1-thread-5===113
pool-1-thread-5===114
pool-1-thread-5===115
pool-1-thread-5===116
pool-1-thread-5===117
pool-1-thread-5===118
pool-1-thread-5===119
pool-1-thread-5===120
pool-1-thread-5===121
pool-1-thread-5===122
pool-1-thread-5===123
pool-1-thread-5===124
pool-1-thread-5===125
pool-1-thread-5===126
pool-1-thread-5===127
pool-1-thread-5===128
pool-1-thread-5===129
pool-1-thread-5===130
pool-1-thread-5===131
pool-1-thread-5===132
pool-1-thread-5===133
pool-1-thread-5===134
pool-1-thread-5===135
pool-1-thread-5===136
pool-1-thread-5===137
pool-1-thread-5===138
pool-1-thread-5===139
pool-1-thread-5===140
pool-1-thread-5===141
pool-1-thread-5===142
pool-1-thread-5===143
pool-1-thread-5===144
pool-1-thread-5===145
pool-1-thread-5===146
pool-1-thread-5===147
pool-1-thread-5===148
pool-1-thread-5===149
pool-1-thread-5===150
pool-1-thread-5===151
pool-1-thread-5===152
pool-1-thread-5===153
pool-1-thread-5===154
pool-1-thread-5===155
pool-1-thread-5===156
pool-1-thread-5===157
pool-1-thread-5===158
pool-1-thread-5===159
pool-1-thread-5===160
pool-1-thread-5===161
pool-1-thread-5===162
pool-1-thread-5===163
pool-1-thread-5===164
pool-1-thread-5===165
pool-1-thread-5===166
pool-1-thread-5===167
pool-1-thread-5===168
pool-1-thread-5===169
pool-1-thread-5===170
pool-1-thread-2===1
pool-1-thread-2===2
pool-1-thread-2===3
pool-1-thread-2===4
pool-1-thread-2===5
pool-1-thread-2===6
pool-1-thread-2===7
pool-1-thread-2===8
pool-1-thread-2===9
pool-1-thread-2===10
pool-1-thread-2===11
pool-1-thread-2===12
pool-1-thread-2===13
pool-1-thread-2===14
pool-1-thread-2===15
pool-1-thread-2===16
pool-1-thread-2===17
pool-1-thread-2===18
pool-1-thread-2===19
pool-1-thread-2===20
pool-1-thread-2===21
pool-1-thread-2===22
pool-1-thread-2===23
pool-1-thread-2===24
pool-1-thread-2===25
pool-1-thread-2===26
pool-1-thread-2===27
pool-1-thread-2===28
pool-1-thread-2===29
pool-1-thread-2===30
pool-1-thread-2===31
pool-1-thread-2===32
pool-1-thread-2===33
pool-1-thread-2===34
pool-1-thread-2===35
pool-1-thread-2===36
pool-1-thread-2===37
pool-1-thread-2===38
pool-1-thread-2===39
pool-1-thread-2===40
pool-1-thread-2===41
pool-1-thread-2===42
pool-1-thread-2===43
pool-1-thread-2===44
pool-1-thread-2===45
pool-1-thread-2===46
pool-1-thread-2===47
pool-1-thread-2===48
pool-1-thread-2===49
pool-1-thread-2===50
pool-1-thread-2===51
pool-1-thread-2===52
pool-1-thread-2===53
pool-1-thread-2===54
pool-1-thread-2===55
pool-1-thread-2===56
pool-1-thread-2===57
pool-1-thread-2===58
pool-1-thread-2===59
pool-1-thread-2===60
pool-1-thread-2===61
pool-1-thread-2===62
pool-1-thread-2===63
pool-1-thread-2===64
pool-1-thread-2===65
pool-1-thread-2===66
pool-1-thread-2===67
pool-1-thread-2===68
pool-1-thread-2===69
pool-1-thread-2===70
pool-1-thread-2===71
pool-1-thread-2===72
pool-1-thread-2===73
pool-1-thread-2===74
pool-1-thread-2===75
pool-1-thread-2===76
pool-1-thread-2===77
pool-1-thread-2===78
pool-1-thread-2===79
pool-1-thread-2===80
pool-1-thread-2===81
pool-1-thread-2===82
pool-1-thread-2===83
pool-1-thread-2===84
pool-1-thread-2===85
pool-1-thread-2===86
pool-1-thread-2===87
pool-1-thread-2===88
pool-1-thread-2===89
pool-1-thread-2===90
pool-1-thread-2===91
pool-1-thread-2===92
pool-1-thread-2===93
pool-1-thread-2===94
pool-1-thread-2===95
pool-1-thread-2===96
pool-1-thread-2===97
pool-1-thread-2===98
pool-1-thread-2===99
pool-1-thread-2===100
pool-1-thread-2===101
pool-1-thread-2===102
pool-1-thread-2===103
pool-1-thread-2===104
pool-1-thread-2===105
pool-1-thread-2===106
pool-1-thread-2===107
pool-1-thread-2===108
pool-1-thread-2===109
pool-1-thread-2===110
pool-1-thread-2===111
pool-1-thread-2===112
pool-1-thread-2===113
pool-1-thread-2===114
pool-1-thread-2===115
pool-1-thread-2===116
pool-1-thread-2===117
pool-1-thread-2===118
pool-1-thread-2===119
pool-1-thread-2===120
pool-1-thread-2===121
pool-1-thread-2===122
pool-1-thread-2===123
pool-1-thread-2===124
pool-1-thread-2===125
pool-1-thread-2===126
pool-1-thread-2===127
pool-1-thread-2===128
pool-1-thread-2===129
pool-1-thread-2===130
pool-1-thread-2===131
pool-1-thread-2===132
pool-1-thread-2===133
pool-1-thread-2===134
pool-1-thread-2===135
pool-1-thread-2===136
pool-1-thread-2===137
pool-1-thread-2===138
pool-1-thread-2===139
pool-1-thread-2===140
pool-1-thread-2===141
pool-1-thread-2===142
pool-1-thread-2===143
pool-1-thread-2===144
pool-1-thread-2===145
pool-1-thread-2===146
pool-1-thread-2===147
pool-1-thread-2===148
pool-1-thread-2===149
pool-1-thread-2===150
pool-1-thread-2===151
pool-1-thread-2===152
pool-1-thread-2===153
pool-1-thread-2===154
pool-1-thread-2===155
pool-1-thread-2===156
pool-1-thread-2===157
pool-1-thread-2===158
pool-1-thread-2===159
pool-1-thread-2===160
pool-1-thread-2===161
pool-1-thread-2===162
pool-1-thread-2===163
pool-1-thread-2===164
pool-1-thread-2===165
pool-1-thread-2===166
pool-1-thread-2===167
pool-1-thread-2===168
pool-1-thread-2===169
pool-1-thread-2===170
pool-1-thread-2===171
pool-1-thread-2===172
pool-1-thread-2===173
pool-1-thread-2===174
pool-1-thread-2===175
pool-1-thread-2===176
pool-1-thread-2===177
pool-1-thread-2===178
pool-1-thread-2===179
pool-1-thread-2===180
pool-1-thread-2===181
pool-1-thread-2===182
pool-1-thread-2===183
pool-1-thread-2===184
pool-1-thread-2===185
pool-1-thread-2===186
pool-1-thread-2===187
pool-1-thread-2===188
pool-1-thread-2===189
pool-1-thread-2===190
pool-1-thread-2===191
pool-1-thread-2===192
pool-1-thread-2===193
pool-1-thread-2===194
pool-1-thread-2===195
pool-1-thread-2===196
pool-1-thread-2===197
pool-1-thread-2===198
pool-1-thread-2===199
pool-1-thread-4===0
pool-1-thread-5===171
pool-1-thread-5===172
pool-1-thread-5===173
pool-1-thread-5===174
pool-1-thread-5===175
pool-1-thread-5===176
pool-1-thread-5===177
pool-1-thread-5===178
pool-1-thread-5===179
pool-1-thread-5===180
pool-1-thread-5===181
pool-1-thread-5===182
pool-1-thread-5===183
pool-1-thread-5===184
pool-1-thread-5===185
pool-1-thread-5===186
pool-1-thread-5===187
pool-1-thread-5===188
pool-1-thread-5===189
pool-1-thread-5===190
pool-1-thread-5===191
pool-1-thread-5===192
pool-1-thread-5===193
pool-1-thread-5===194
pool-1-thread-5===195
pool-1-thread-5===196
pool-1-thread-5===197
pool-1-thread-5===198
pool-1-thread-5===199
pool-1-thread-1===3
pool-1-thread-1===4
pool-1-thread-1===5
pool-1-thread-1===6
pool-1-thread-1===7
pool-1-thread-1===8
pool-1-thread-1===9
pool-1-thread-1===10
pool-1-thread-1===11
pool-1-thread-1===12
pool-1-thread-1===13
pool-1-thread-1===14
pool-1-thread-1===15
pool-1-thread-1===16
pool-1-thread-1===17
pool-1-thread-1===18
pool-1-thread-1===19
pool-1-thread-1===20
pool-1-thread-1===21
pool-1-thread-1===22
pool-1-thread-1===23
pool-1-thread-1===24
pool-1-thread-1===25
pool-1-thread-1===26
pool-1-thread-1===27
pool-1-thread-1===28
pool-1-thread-1===29
pool-1-thread-1===30
pool-1-thread-1===31
pool-1-thread-1===32
pool-1-thread-1===33
pool-1-thread-1===34
pool-1-thread-1===35
pool-1-thread-1===36
pool-1-thread-1===37
pool-1-thread-1===38
pool-1-thread-1===39
pool-1-thread-1===40
pool-1-thread-1===41
pool-1-thread-1===42
pool-1-thread-1===43
pool-1-thread-1===44
pool-1-thread-1===45
pool-1-thread-1===46
pool-1-thread-1===47
pool-1-thread-1===48
pool-1-thread-1===49
pool-1-thread-1===50
pool-1-thread-1===51
pool-1-thread-1===52
pool-1-thread-1===53
pool-1-thread-1===54
pool-1-thread-1===55
pool-1-thread-1===56
pool-1-thread-1===57
pool-1-thread-1===58
pool-1-thread-1===59
pool-1-thread-1===60
pool-1-thread-1===61
pool-1-thread-1===62
pool-1-thread-1===63
pool-1-thread-1===64
pool-1-thread-1===65
pool-1-thread-1===66
pool-1-thread-1===67
pool-1-thread-1===68
pool-1-thread-1===69
pool-1-thread-1===70
pool-1-thread-1===71
pool-1-thread-1===72
pool-1-thread-1===73
pool-1-thread-1===74
pool-1-thread-1===75
pool-1-thread-1===76
pool-1-thread-1===77
pool-1-thread-1===78
pool-1-thread-1===79
pool-1-thread-1===80
pool-1-thread-1===81
pool-1-thread-1===82
pool-1-thread-1===83
pool-1-thread-1===84
pool-1-thread-1===85
pool-1-thread-1===86
pool-1-thread-1===87
pool-1-thread-1===88
pool-1-thread-1===89
pool-1-thread-1===90
pool-1-thread-1===91
pool-1-thread-1===92
pool-1-thread-1===93
pool-1-thread-1===94
pool-1-thread-1===95
pool-1-thread-1===96
pool-1-thread-1===97
pool-1-thread-1===98
pool-1-thread-1===99
pool-1-thread-1===100
pool-1-thread-1===101
pool-1-thread-1===102
pool-1-thread-1===103
pool-1-thread-1===104
pool-1-thread-1===105
pool-1-thread-4===1
pool-1-thread-1===106
pool-1-thread-4===2
pool-1-thread-1===107
pool-1-thread-1===108
pool-1-thread-1===109
pool-1-thread-1===110
pool-1-thread-1===111
pool-1-thread-1===112
pool-1-thread-1===113
pool-1-thread-1===114
pool-1-thread-1===115
pool-1-thread-1===116
pool-1-thread-1===117
pool-1-thread-1===118
pool-1-thread-1===119
pool-1-thread-1===120
pool-1-thread-1===121
pool-1-thread-1===122
pool-1-thread-1===123
pool-1-thread-1===124
pool-1-thread-1===125
pool-1-thread-1===126
pool-1-thread-1===127
pool-1-thread-1===128
pool-1-thread-1===129
pool-1-thread-1===130
pool-1-thread-1===131
pool-1-thread-1===132
pool-1-thread-1===133
pool-1-thread-1===134
pool-1-thread-1===135
pool-1-thread-1===136
pool-1-thread-1===137
pool-1-thread-1===138
pool-1-thread-1===139
pool-1-thread-1===140
pool-1-thread-1===141
pool-1-thread-1===142
pool-1-thread-1===143
pool-1-thread-1===144
pool-1-thread-1===145
pool-1-thread-1===146
pool-1-thread-1===147
pool-1-thread-1===148
pool-1-thread-1===149
pool-1-thread-1===150
pool-1-thread-1===151
pool-1-thread-1===152
pool-1-thread-1===153
pool-1-thread-1===154
pool-1-thread-1===155
pool-1-thread-1===156
pool-1-thread-1===157
pool-1-thread-1===158
pool-1-thread-1===159
pool-1-thread-1===160
pool-1-thread-1===161
pool-1-thread-1===162
pool-1-thread-1===163
pool-1-thread-1===164
pool-1-thread-1===165
pool-1-thread-1===166
pool-1-thread-1===167
pool-1-thread-1===168
pool-1-thread-1===169
pool-1-thread-1===170
pool-1-thread-1===171
pool-1-thread-1===172
pool-1-thread-1===173
pool-1-thread-1===174
pool-1-thread-1===175
pool-1-thread-1===176
pool-1-thread-1===177
pool-1-thread-1===178
pool-1-thread-1===179
pool-1-thread-1===180
pool-1-thread-1===181
pool-1-thread-1===182
pool-1-thread-1===183
pool-1-thread-1===184
pool-1-thread-1===185
pool-1-thread-1===186
pool-1-thread-1===187
pool-1-thread-1===188
pool-1-thread-1===189
pool-1-thread-1===190
pool-1-thread-1===191
pool-1-thread-1===192
pool-1-thread-1===193
pool-1-thread-1===194
pool-1-thread-1===195
pool-1-thread-1===196
pool-1-thread-1===197
pool-1-thread-1===198
pool-1-thread-1===199
pool-1-thread-1===236
pool-1-thread-2===231
pool-1-thread-4===3
pool-1-thread-4===4
pool-1-thread-4===5
pool-1-thread-4===6
pool-1-thread-4===7
pool-1-thread-4===8
pool-1-thread-4===9
pool-1-thread-4===10
pool-1-thread-4===11
pool-1-thread-4===12
pool-1-thread-4===13
pool-1-thread-4===14
pool-1-thread-4===15
pool-1-thread-4===16
pool-1-thread-4===17
pool-1-thread-4===18
pool-1-thread-4===19
pool-1-thread-4===20
pool-1-thread-4===21
pool-1-thread-4===22
pool-1-thread-4===23
pool-1-thread-4===24
pool-1-thread-4===25
pool-1-thread-4===26
pool-1-thread-4===27
pool-1-thread-4===28
pool-1-thread-4===29
pool-1-thread-4===30
pool-1-thread-4===31
pool-1-thread-4===32
pool-1-thread-4===33
pool-1-thread-4===34
pool-1-thread-4===35
pool-1-thread-4===36
pool-1-thread-3===22
pool-1-thread-4===37
pool-1-thread-4===38
pool-1-thread-4===39
pool-1-thread-4===40
pool-1-thread-4===41
pool-1-thread-4===42
pool-1-thread-4===43
pool-1-thread-4===44
pool-1-thread-4===45
pool-1-thread-4===46
pool-1-thread-4===47
pool-1-thread-4===48
pool-1-thread-4===49
pool-1-thread-4===50
pool-1-thread-4===51
pool-1-thread-4===52
pool-1-thread-4===53
pool-1-thread-4===54
pool-1-thread-4===55
pool-1-thread-4===56
pool-1-thread-4===57
pool-1-thread-4===58
pool-1-thread-4===59
pool-1-thread-4===60
pool-1-thread-4===61
pool-1-thread-4===62
pool-1-thread-4===63
pool-1-thread-4===64
pool-1-thread-4===65
pool-1-thread-4===66
pool-1-thread-4===67
pool-1-thread-4===68
pool-1-thread-4===69
pool-1-thread-4===70
pool-1-thread-4===71
pool-1-thread-4===72
pool-1-thread-4===73
pool-1-thread-4===74
pool-1-thread-4===75
pool-1-thread-4===76
pool-1-thread-4===77
pool-1-thread-4===78
pool-1-thread-4===79
pool-1-thread-4===80
pool-1-thread-4===81
pool-1-thread-4===82
pool-1-thread-4===83
pool-1-thread-4===84
pool-1-thread-4===85
pool-1-thread-4===86
pool-1-thread-4===87
pool-1-thread-4===88
pool-1-thread-4===89
pool-1-thread-4===90
pool-1-thread-4===91
pool-1-thread-4===92
pool-1-thread-4===93
pool-1-thread-4===94
pool-1-thread-4===95
pool-1-thread-4===96
pool-1-thread-4===97
pool-1-thread-4===98
pool-1-thread-4===99
pool-1-thread-4===100
pool-1-thread-4===101
pool-1-thread-4===102
pool-1-thread-4===103
pool-1-thread-4===104
pool-1-thread-4===105
pool-1-thread-4===106
pool-1-thread-4===107
pool-1-thread-4===108
pool-1-thread-4===109
pool-1-thread-4===110
pool-1-thread-4===111
pool-1-thread-4===112
pool-1-thread-4===113
pool-1-thread-4===114
pool-1-thread-4===115
pool-1-thread-4===116
pool-1-thread-4===117
pool-1-thread-4===118
pool-1-thread-4===119
pool-1-thread-4===120
pool-1-thread-4===121
pool-1-thread-4===122
pool-1-thread-4===123
pool-1-thread-4===124
pool-1-thread-4===125
pool-1-thread-4===126
pool-1-thread-4===127
pool-1-thread-4===128
pool-1-thread-4===129
pool-1-thread-4===130
pool-1-thread-4===131
pool-1-thread-4===132
pool-1-thread-4===133
pool-1-thread-4===134
pool-1-thread-4===135
pool-1-thread-4===136
pool-1-thread-4===137
pool-1-thread-4===138
pool-1-thread-4===139
pool-1-thread-4===140
pool-1-thread-4===141
pool-1-thread-4===142
pool-1-thread-4===143
pool-1-thread-4===144
pool-1-thread-4===145
pool-1-thread-4===146
pool-1-thread-4===147
pool-1-thread-4===148
pool-1-thread-4===149
pool-1-thread-4===150
pool-1-thread-4===151
pool-1-thread-4===152
pool-1-thread-4===153
pool-1-thread-4===154
pool-1-thread-4===155
pool-1-thread-4===156
pool-1-thread-4===157
pool-1-thread-4===158
pool-1-thread-4===159
pool-1-thread-4===160
pool-1-thread-4===161
pool-1-thread-4===162
pool-1-thread-4===163
pool-1-thread-4===164
pool-1-thread-4===165
pool-1-thread-4===166
pool-1-thread-4===167
pool-1-thread-4===168
pool-1-thread-4===169
pool-1-thread-4===170
pool-1-thread-4===171
pool-1-thread-4===172
pool-1-thread-4===173
pool-1-thread-4===174
pool-1-thread-4===175
pool-1-thread-4===176
pool-1-thread-4===177
pool-1-thread-4===178
pool-1-thread-4===179
pool-1-thread-4===180
pool-1-thread-4===181
pool-1-thread-4===182
pool-1-thread-4===183
pool-1-thread-4===184
pool-1-thread-4===185
pool-1-thread-4===186
pool-1-thread-4===187
pool-1-thread-4===188
pool-1-thread-4===189
pool-1-thread-4===190
pool-1-thread-4===191
pool-1-thread-4===192
pool-1-thread-4===193
pool-1-thread-4===194
pool-1-thread-4===195
pool-1-thread-4===196
pool-1-thread-4===197
pool-1-thread-4===198
pool-1-thread-4===199
pool-1-thread-4===233
pool-1-thread-5===210

其实还有一只callable的写法

实现Callable接口通过FutureTask包装器来创建Thread线程

package cn.itcast_02;

import java.util.concurrent.Callable;

public class MyThread_04<String> implements Callable<String> {

	@Override
	 //重写call()方法,切记抛出异常,并返回值
	public String call() throws Exception {
		long start = System.currentTimeMillis(); // 记录起始时间
		// 一般来说,被线程执行的代码肯定是比较耗时的。所以我们用循环改进模拟
		for (int x = 0; x < 200; x++) {
			System.out.println(Thread.currentThread().getName()+"==="+x);
			
		}
		long end =System.currentTimeMillis();
		return (String) (Thread.currentThread().getName()+"==="+(end-start));
	}

}
测试类:
package cn.itcast_02.test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

import cn.itcast_02.MyThread_04;

public class MyThread_04Test {

	public static void main(String[] args) {

		MyThread_04<String> mt_04=	new MyThread_04<String>();
		//包装对象
        FutureTask<String> ft = new FutureTask<String>(mt_04);
       
		
		new Thread(ft).start();
		

		try {
			System.out.println("运行结果" +ft.get());
		} catch (InterruptedException | ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

运行结果:
Thread-0===0
Thread-0===1
Thread-0===2
Thread-0===3
Thread-0===4
Thread-0===5
Thread-0===6
Thread-0===7
Thread-0===8
Thread-0===9
Thread-0===10
Thread-0===11
Thread-0===12
Thread-0===13
Thread-0===14
Thread-0===15
Thread-0===16
Thread-0===17
Thread-0===18
Thread-0===19
Thread-0===20
Thread-0===21
Thread-0===22
Thread-0===23
Thread-0===24
Thread-0===25
Thread-0===26
Thread-0===27
Thread-0===28
Thread-0===29
Thread-0===30
Thread-0===31
Thread-0===32
Thread-0===33
Thread-0===34
Thread-0===35
Thread-0===36
Thread-0===37
Thread-0===38
Thread-0===39
Thread-0===40
Thread-0===41
Thread-0===42
Thread-0===43
Thread-0===44
Thread-0===45
Thread-0===46
Thread-0===47
Thread-0===48
Thread-0===49
Thread-0===50
Thread-0===51
Thread-0===52
Thread-0===53
Thread-0===54
Thread-0===55
Thread-0===56
Thread-0===57
Thread-0===58
Thread-0===59
Thread-0===60
Thread-0===61
Thread-0===62
Thread-0===63
Thread-0===64
Thread-0===65
Thread-0===66
Thread-0===67
Thread-0===68
Thread-0===69
Thread-0===70
Thread-0===71
Thread-0===72
Thread-0===73
Thread-0===74
Thread-0===75
Thread-0===76
Thread-0===77
Thread-0===78
Thread-0===79
Thread-0===80
Thread-0===81
Thread-0===82
Thread-0===83
Thread-0===84
Thread-0===85
Thread-0===86
Thread-0===87
Thread-0===88
Thread-0===89
Thread-0===90
Thread-0===91
Thread-0===92
Thread-0===93
Thread-0===94
Thread-0===95
Thread-0===96
Thread-0===97
Thread-0===98
Thread-0===99
Thread-0===100
Thread-0===101
Thread-0===102
Thread-0===103
Thread-0===104
Thread-0===105
Thread-0===106
Thread-0===107
Thread-0===108
Thread-0===109
Thread-0===110
Thread-0===111
Thread-0===112
Thread-0===113
Thread-0===114
Thread-0===115
Thread-0===116
Thread-0===117
Thread-0===118
Thread-0===119
Thread-0===120
Thread-0===121
Thread-0===122
Thread-0===123
Thread-0===124
Thread-0===125
Thread-0===126
Thread-0===127
Thread-0===128
Thread-0===129
Thread-0===130
Thread-0===131
Thread-0===132
Thread-0===133
Thread-0===134
Thread-0===135
Thread-0===136
Thread-0===137
Thread-0===138
Thread-0===139
Thread-0===140
Thread-0===141
Thread-0===142
Thread-0===143
Thread-0===144
Thread-0===145
Thread-0===146
Thread-0===147
Thread-0===148
Thread-0===149
Thread-0===150
Thread-0===151
Thread-0===152
Thread-0===153
Thread-0===154
Thread-0===155
Thread-0===156
Thread-0===157
Thread-0===158
Thread-0===159
Thread-0===160
Thread-0===161
Thread-0===162
Thread-0===163
Thread-0===164
Thread-0===165
Thread-0===166
Thread-0===167
Thread-0===168
Thread-0===169
Thread-0===170
Thread-0===171
Thread-0===172
Thread-0===173
Thread-0===174
Thread-0===175
Thread-0===176
Thread-0===177
Thread-0===178
Thread-0===179
Thread-0===180
Thread-0===181
Thread-0===182
Thread-0===183
Thread-0===184
Thread-0===185
Thread-0===186
Thread-0===187
Thread-0===188
Thread-0===189
Thread-0===190
Thread-0===191
Thread-0===192
Thread-0===193
Thread-0===194
Thread-0===195
Thread-0===196
Thread-0===197
Thread-0===198
Thread-0===199
运行结果Thread-0===15

二、多线程实现的接口和类

        从上面多线的实现方式中,我们发现多线程实现主要有两个关键的元素:Runnable接口和Thread类。

由于线程是依赖进程而存在的,所以多线程的实现中我们应该先创建一个进程出来。而进程是由系统创建的,所以我们应该去调用系统功能创建一个进程。Java是不能直接调用系统功能的,所以,我们没有办法直接实现多线程程序。但是呢?Java可以去调用C/C++写好的程序来实现多线程程序。由C/C++去调用系统功能创建进程,然后由Java去调用这样的东西,然后提供一些接口或者类供我们使用。我们就可以实现多线程程序了。

Java提供的接口和类:Runnable接口和Thread类。

2.1 Runnable接口


package java.lang;

/**
 * @author  Arthur van Hoff
 * @see     java.lang.Thread
 * @see     java.util.concurrent.Callable
 * @since   JDK1.0
 */
@FunctionalInterface
public interface Runnable {
    /**
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

接口只有一个run方法,并没有其他的东西。而thread也有run方法,那么这两者有什么联系呢?

2.2Thread类

package java.lang;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.LockSupport;
import sun.nio.ch.Interruptible;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;


/**
 * @author  unascribed
 * @see     Runnable
 * @see     Runtime#exit(int)
 * @see     #run()
 * @see     #stop()
 * @since   JDK1.0
 */
//Thread本身也是继承了Runnable接口
public class Thread implements Runnable {

   
   /**
    * 定义了一个静态初始化块,我们知道当创建Java对象时,系统总是先调用静态初始化块
    * 静态初始化块中调用了registerNatives()方法,并且使用了private来修饰,表面这个方法是私有的并不被外部调用。
    * 在Java中使用native关键字修饰的方法,说明此方法并不是由Java中完成的,而是通过C/C++来完成的,并被编译成.dll,之后才由Java调用。
	* 方法的具体实现是在dll文件中,当然对于不同平台实现的细节也有所不同,以上registerNatives()方法主要作用就是将C/C++中的方法映射到Java中的native方法,实现方法命名的解耦
    */
   
    private static native void registerNatives();
	
    static {
        registerNatives();
    }
	
    /** 线程名字*/
    private volatile String name;
	/**优先级 */
    private int            priority;
	/** */
    private Thread         threadQ;
	/* */
    private long           eetop;

   /**是否是单步执行*/
    private boolean     single_step;

    /**是否是守护线程*/
    private boolean     daemon = false;

    /** 虚拟机状态 */
    private boolean     stillborn = false;

    /** 实际的线程任务即将会被执行的Runnable */
    private Runnable target;

    /** 这个线程的组
	  *ThreadGroup作用: 
	  * 1.ThreadGroup可以遍历线程,知道哪些线程已经运行完毕,哪些还在运行;
	  * 2.可以通过ThreadGroup.activeCount()知道有多少线程从而可以控制插入的线程数。 
	  *
	  *
	  */
    private ThreadGroup group;

    /** 这个线程的上下文 */
    private ClassLoader contextClassLoader;

    /**继承的请求控制 */
    private AccessControlContext inheritedAccessControlContext;

    /** 默认线程的自动编号 */
    private static int threadInitNumber;
    private static synchronized int nextThreadNum() {
        return threadInitNumber++;
    }

    /** 当前线程附属的ThreadLocal,而ThreadLocalMap会被ThreadLocal维护 */
    ThreadLocal.ThreadLocalMap threadLocals = null;

    /**
     * 主要作用:为子线程提供从父线程那里继承的值
	 * 在创建子线程时,子线程会接收所有可继承的线程局部变量的初始值,以获得父线程所具有的值
	 * 创建一个线程时如果保存了所有 InheritableThreadLocal 对象的值,那么这些值也将自动传递给子线程
	 * 如果一个子线程调用 InheritableThreadLocal 的 get() ,那么它将与它的父线程看到同一个对象
     * maintained by the InheritableThreadLocal class.
     */
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

    /**
     * 该线程请求的堆栈大小 默认一般都是忽略
     */
    private long stackSize;

    /**
     * JVM-private state that persists after native thread termination.
     */
    private long nativeParkEventPointer;

    /**
     * 每个线程都有专属ID,但名字可能重复
     */
    private long tid;

    
    private static long threadSeqNumber;

    /** 
     * 标识线程状态,默认是线程未启动
     */

    private volatile int threadStatus = 0;

    /** 用来生成thread ID*/
    private static synchronized long nextThreadID() {
        return ++threadSeqNumber;
    }

    /**
     * 中断阻塞器:当线程发生IO中断时,需要在线程被设置为中断状态后调用该对象的interrupt方法
     */
    volatile Object parkBlocker;

    /** 阻断锁
     */
    private volatile Interruptible blocker;
	
    private final Object blockerLock = new Object();

    /* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
     */
    void blockedOn(Interruptible b) {
        synchronized (blockerLock) {
            blocker = b;
        }
    }

    /**
     * 线程的优先级中最小的.java中的线程总共分了10个优先级最小优先级为1,最大为10,默认为5
     */
    public final static int MIN_PRIORITY = 1;

   /**
     *线程的优先级中第二的同时也是默认的优先级.java中的线程总共分了10个优先级最小优先级为1,最大为10,默认为5
     */
    public final static int NORM_PRIORITY = 5;

    /**
     * 最高的优先级java中的线程总共分了10个优先级最小优先级为1,最大为10,默认为5
     */
    public final static int MAX_PRIORITY = 10;

    /**一些静态native方法,由jvm实现
     * 
     *返回对当前正在执行的线程对象的引用
     * @return  the currently executing thread.
     */
    public static native Thread currentThread();

    /**一些静态native方法,由jvm实现
     * 
	 *暂停当前正在执行的线程对象,并执行其他线程。
     */
    public static native void yield();

    /**一些静态native方法,由jvm实现
     * 
     * 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响
     */
    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)) {
            millis++;
        }

        sleep(millis);
    }

    /**
     * 最主要的辅助构造函数,所有的构造函数均调用init函数
	 * g是线程组,target被调用RUN方法的目标对象,name新线程的名字,stackSize用于新线程分配所需堆栈大小
     * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext)
     */
    private void init(ThreadGroup g, Runnable target, String name,long stackSize) {
                      
        init(g, target, name, stackSize, null);
    }

    /**
     * 最主要的辅助构造函数,所有的构造函数均调用init函数
	 * g是线程组,target被调用RUN方法的目标对象,name新线程的名字,stackSize用于新线程分配所需堆栈大小,acc调用上下文
     */
    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;
		/*获得当前线程*/
        Thread parent = currentThread();
		/*获得系统的安全管理器*/
        SecurityManager security = System.getSecurityManager();
		
        if (g == null) {
            /*安全检查--- 如果系统的安全管理器不为空,从系统中获取线程组*/
            if (security != null) {
                g = security.getThreadGroup();
            }
			/*设置线程组--如果系统的安全管理器为空,从parent中获取线程组 */
            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();
		/*每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。
		 *当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。*/
        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);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;

        /* 获取唯一的线程id,此函数为synchronize */
        tid = nextThreadID();
    }

    /**
     * Throws CloneNotSupportedException as a Thread can not be meaningfully
     * cloned. Construct a new Thread instead.
     *
     * @throws  CloneNotSupportedException
     *          always
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }

    /**
	 *无参的构造函数
     */
    public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }

    /**
	 *带有一个参数Runnable接口实现对象target的构造函数
     */
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

    /**
     * Creates a new Thread that inherits the given AccessControlContext.
     * This is not a public constructor.
     */
    Thread(Runnable target, AccessControlContext acc) {
        init(null, target, "Thread-" + nextThreadNum(), 0, acc);
    }

    /**
     * 带有两个参数线程组group和Runnable接口实现对象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);
    }

    /**
     * 带有两个参数Runnable接口实现对象target和线程名name的构造函数
     */
    public Thread(Runnable target, String name) {
        init(null, target, name, 0);
    }

    /**
     * 带有三个参数线程组group、Runnable接口实现对象target、线程名name的构造函数 
     */
    public Thread(ThreadGroup group, Runnable target, String name) {
        init(group, target, name, 0);
    }

    /**
     * 带有四个个参数线程组group、Runnable接口实现对象target、线程名name、新线程分配所需堆栈大小stackSize的构造函数 
     */
    public Thread(ThreadGroup group, Runnable target, String name,
                  long stackSize) {
        init(group, target, name, stackSize);
    }

    /**
     * 使线程进入可执行(runnable状态)的状态 
	 * 调用start方法后线程状态不再是新建状态(NEW),而是变成运行态。 
	 * 所以如果对一个线程对象多次调用start方法的话,会产生:IllegalThreadStateException异常。
     */
    public synchronized void start() {
		/*验证线程的状态,如果线程已启动则抛异常*/
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /*向线程组里添加此线程*/
        group.add(this);
		/*设置一个可执行状态标志*/
        boolean started = false;
        try {
			/*使线程进入可执行(runnable状态)的状态*/
            start0();
			/*修改标志*/
            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 */
            }
        }
    }
	/*本地方法start0()*/
    private native void start0();

    /**
     * 使线程从可运行状态转化为运行状态
     * 
     */
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

    /**
     * 这个方法是在Run方法执行结束后用于结束线程的。通过单步调试一个线程发现执行完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;
    }

    /**
     * 停止线程---该方法已经过时
     * 
     *       
     */
    @Deprecated
    public final void stop() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            checkAccess();
            if (this != Thread.currentThread()) {
                security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
            }
        }
        // A zero status value corresponds to "NEW", it can't change to
        // not-NEW because we hold the lock.
        if (threadStatus != 0) {
            resume(); // Wake up thread if it was suspended; no-op otherwise
        }

        // 执行Stop0
        stop0(new ThreadDeath());
    }

    /**---该方法已经过时
     * 停止线程
     *       
     */
    @Deprecated
    public final synchronized void stop(Throwable obj) {
        throw new UnsupportedOperationException();
    }

    /**
     * interrupt()方法用于中断线程。调用该方法的线程的状态为将被置为"中断"状态。
	 * 注意:线程中断仅仅是设置线程的中断状态位,即设置为true,不会停止线程。
	 * 中断的结果线程是死亡还是等待新的任务或是继续运行至,取决于这个程序本身。
	 * 线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。
	 * 设置线程的中断状态位,在线程受到阻塞的地方(如调用sleep、wait、join等地方)抛出一个异常InterruptedException,并且中断状态也将被清除,这样线程就得以退出阻塞的状态。
     */
    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // 仅仅是设置线程的中断状态位
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }

    /**
     * 测试当前线程是否已经中断。线程的中断状态 由该方法清除。
	 * 换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。 
	 * 直接调用当前线程的isInterrupted(true)方法。interrupted是作用于当前线程,isInterrupted 是作用于调用该方法的线程对象所对应的线程。
	 * 注意:线程对象对应的线程不一定是当前运行的线程。例如可以在A线程中去调用B线程对象的isInterrupted方法。
     */
    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }

    /**
     * 测试线程是否已经中断。线程的中断状态 不受该方法的影响。 
     */
    public boolean isInterrupted() {
        return isInterrupted(false);
    }

    /**
     *私有本地调用的方法
	 *通过参数名可以知道,ClearInterrupted参数代表是否要清除状态位。 
     */
    private native boolean isInterrupted(boolean ClearInterrupted);

    /**----已过时
     *该方法最初用于破坏该线程,但不作任何清除。
	 *它所保持的任何监视器都会保持锁定状态。不过,该方法决不会被实现。
     */
    @Deprecated
    public void destroy() {
        throw new NoSuchMethodError();
    }

    /**
     * 
     * 测试线程是否处于活动状态。如果线程已经启动且尚未终止,则为活动状态
     *
     */
    public final native boolean isAlive();

    /**----已过时
     * 该方法已经遭到反对,因为它具有固有的死锁倾向。如果目标线程挂起时在保护关键系统资源的监视器上保持有锁,则在目标线程重新开始以前任何线程都不能访问该资源。
	 * 如果重新开始目标线程的线程想在调用 resume 之前锁定该监视器,则会发生死锁。这类死锁通常会证明自己是“冻结”的进程。
     * 
     */
    @Deprecated
    public final void suspend() {
        checkAccess();
        suspend0();
    }

    /**----已过时
     * 重新开始挂起的进程。该方法只与 suspend() 一起使用,但 suspend() 已经遭到反对,因为它具有死锁倾向。
     */
    @Deprecated
    public final void resume() {
        checkAccess();
        resume0();
    }

    /**
     * 设置线程的优先级
     */
    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;
    }

    /**
     *设置线程名称
     */
    public final synchronized void setName(String name) {
        checkAccess();
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        this.name = name;
        if (threadStatus != 0) {
            setNativeName(name);
        }
    }

    /**
     * 获取线程名称
     */
    public final String getName() {
        return name;
    }

    /**
     *获取线程组
     */
    public final ThreadGroup getThreadGroup() {
        return group;
    }

    /**
     * 返回当前线程的线程组中活动线程的数目
     */
    public static int activeCount() {
        return currentThread().getThreadGroup().activeCount();
    }

    /**
     *将当前线程的线程组及其子组中的每一个活动线程复制到指定的数组中。
     */
    public static int enumerate(Thread tarray[]) {
        return currentThread().getThreadGroup().enumerate(tarray);
    }

    /**----已过时
     *计算该线程中的堆栈帧数。线程必须挂起
     */
    @Deprecated
    public native int countStackFrames();

    /**
     * 等待该线程终止的时间最长为 millis 毫秒。超时为 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);
                now = System.currentTimeMillis() - base;
            }
        }
    }

    /**
     * 
     * 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒 
     */
    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);
    }

    /**
     *
     * 等待该线程终止。
     * 
     */
    public final void join() throws InterruptedException {
        join(0);
    }

    /**
     *将当前线程的堆栈跟踪打印至标准错误流。该方法仅用于调试。
     */
    public static void dumpStack() {
        new Exception("Stack trace").printStackTrace();
    }

    /**
     * 将该线程标记为守护线程或用户线程。
     * 注意:
     *      a.当正在运行的线程都是守护线程时,Java 虚拟机退出。
     *      b.该方法必须在启动线程前调用。
     *         
     *
     */
    public final void setDaemon(boolean on) {
        checkAccess();
        if (isAlive()) {
            throw new IllegalThreadStateException();
        }
        daemon = on;
    }

    /**
	 *测试该线程是否为守护线程
     */
    public final boolean isDaemon() {
        return daemon;
    }

    /**
     * 判定当前运行的线程是否有权修改该线程
     */
    public final void checkAccess() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
			/*如果有安全管理器,则调用其 checkAccess 方法,并将该线程作为其参数。这可能导致抛出 SecurityException。*/
            security.checkAccess(this);
        }
    }

    /**
     *返回该线程的字符串表示形式,包括线程名称、优先级和线程组
     */
    public String toString() {
        ThreadGroup group = getThreadGroup();
        if (group != null) {
            return "Thread[" + getName() + "," + getPriority() + "," +
                           group.getName() + "]";
        } else {
            return "Thread[" + getName() + "," + getPriority() + "," +
                            "" + "]";
        }
    }

    /**
     * 返回该线程的上下文 ClassLoader。上下文 ClassLoader 由线程创建者提供,供运行于该线程中的代码在加载类和资源时使用。
     * 如果未设定,则默认为父线程的 ClassLoader 上下文。
     * 原始线程的上下文 ClassLoader 通常设定为用于加载应用程序的类加载器。
     */
    @CallerSensitive
    public ClassLoader getContextClassLoader() {
        if (contextClassLoader == null)
            return null;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            ClassLoader.checkClassLoaderPermission(contextClassLoader,
                                                   Reflection.getCallerClass());
        }
        return contextClassLoader;
    }

    /**
     *设置该线程的上下文 ClassLoader。
     *上下文 ClassLoader 可以在创建线程设置,并允许创建者在加载类和资源时向该线程中运行的代码提供适当的类加载器。
     *
     *
     * 
     */
    public void setContextClassLoader(ClassLoader cl) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("setContextClassLoader"));
        }
        contextClassLoader = cl;
    }

    /**
     *当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。
     * 该方法旨在使程序能够断言当前线程已经保持一个指定的锁:assert Thread.holdsLock(obj);
     *
     * 
     */
    public static native boolean holdsLock(Object obj);

    private static final StackTraceElement[] EMPTY_STACK_TRACE
        = new StackTraceElement[0];

    /**
     * 返回一个表示该线程堆栈转储的堆栈跟踪元素数组。
	 * 如果该线程尚未启动或已经终止,则该方法将返回一个零长度数组。
	 * 如果返回的数组不是零长度的,则其第一个元素代表堆栈顶,它是该序列中最新的方法调用。
	 * 最后一个元素代表堆栈底,是该序列中最旧的方法调用。
     * @since 1.5
     */
    public StackTraceElement[] getStackTrace() {
        if (this != Thread.currentThread()) {
            // check for getStackTrace permission
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkPermission(
                    SecurityConstants.GET_STACK_TRACE_PERMISSION);
            }
            // optimization so we do not call into the vm for threads that
            // have not yet started or have terminated
            if (!isAlive()) {
                return EMPTY_STACK_TRACE;
            }
            StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
            StackTraceElement[] stackTrace = stackTraceArray[0];
            // a thread that was alive during the previous isAlive call may have
            // since terminated, therefore not having a stacktrace.
            if (stackTrace == null) {
                stackTrace = EMPTY_STACK_TRACE;
            }
            return stackTrace;
        } else {
            // Don't need JVM help for current thread
            return (new Exception()).getStackTrace();
        }
    }

    /**
     * 返回所有活动线程的堆栈跟踪的一个映射。
	 * 映射键是线程,而每个映射值都是一个 StackTraceElement 数组,该数组表示相应 Thread 的堆栈转储。
     * 返回的堆栈跟踪的格式都是针对 getStackTrace 方法指定的。 
	 * 在调用该方法的同时,线程可能也在执行。每个线程的堆栈跟踪仅代表一个快照,并且每个堆栈跟踪都可以在不同时间获得。
	 * 如果虚拟机没有线程的堆栈跟踪信息,则映射值中将返回一个零长度数组。 
	 */
    public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
        // check for getStackTrace permission
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(
                SecurityConstants.GET_STACK_TRACE_PERMISSION);
            security.checkPermission(
                SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
        }

        // Get a snapshot of the list of all threads
        Thread[] threads = getThreads();
        StackTraceElement[][] traces = dumpThreads(threads);
        Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
        for (int i = 0; i < threads.length; i++) {
            StackTraceElement[] stackTrace = traces[i];
            if (stackTrace != null) {
                m.put(threads[i], stackTrace);
            }
            // else terminated so we don't put it in the map
        }
        return m;
    }


    private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
                    new RuntimePermission("enableContextClassLoaderOverride");

    /** cache of subclass security audit results */
    /* Replace with ConcurrentReferenceHashMap when/if it appears in a future
     * release */
    private static class Caches {
        /** cache of subclass security audit results */
        static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
            new ConcurrentHashMap<>();

        /** queue for WeakReferences to audited subclasses */
        static final ReferenceQueue<Class<?>> subclassAuditsQueue =
            new ReferenceQueue<>();
    }

    /**
     * Verifies that this (possibly subclass) instance can be constructed
     * without violating security constraints: the subclass must not override
     * security-sensitive non-final methods, or else the
     * "enableContextClassLoaderOverride" RuntimePermission is checked.
     */
    private static boolean isCCLOverridden(Class<?> cl) {
        if (cl == Thread.class)
            return false;

        processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
        WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
        Boolean result = Caches.subclassAudits.get(key);
        if (result == null) {
            result = Boolean.valueOf(auditSubclass(cl));
            Caches.subclassAudits.putIfAbsent(key, result);
        }

        return result.booleanValue();
    }

    /**
     * Performs reflective checks on given subclass to verify that it doesn't
     * override security-sensitive non-final methods.  Returns true if the
     * subclass overrides any of the methods, false otherwise.
     */
    private static boolean auditSubclass(final Class<?> subcl) {
        Boolean result = AccessController.doPrivileged(
            new PrivilegedAction<Boolean>() {
                public Boolean run() {
                    for (Class<?> cl = subcl;
                         cl != Thread.class;
                         cl = cl.getSuperclass())
                    {
                        try {
                            cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
                            return Boolean.TRUE;
                        } catch (NoSuchMethodException ex) {
                        }
                        try {
                            Class<?>[] params = {ClassLoader.class};
                            cl.getDeclaredMethod("setContextClassLoader", params);
                            return Boolean.TRUE;
                        } catch (NoSuchMethodException ex) {
                        }
                    }
                    return Boolean.FALSE;
                }
            }
        );
        return result.booleanValue();
    }

    private native static StackTraceElement[][] dumpThreads(Thread[] threads);
    private native static Thread[] getThreads();

    /**
     * Returns the identifier of this Thread.  The thread ID is a positive
     * <tt>long</tt> number generated when this thread was created.
     * The thread ID is unique and remains unchanged during its lifetime.
     * When a thread is terminated, this thread ID may be reused.
     *
     * @return this thread's ID.
     * @since 1.5
     */
    public long getId() {
        return tid;
    }

    /**
     * 
     *
     * JVM中的线程必须只能是以下6种状态的一种。这些状态是JVM状态并不能和操作系统线程状态互相映射。
     */
    public enum State {
        /**
		 * 线程刚创建,还未执行(start方法)
         */
        NEW,

        /**
         * 已就绪可运行的状态。
		 * 处于此状态的线程是正在JVM中运行的,但可能在等待操作系统级别的资源,例如CPU时间片
         */
        RUNNABLE,

        /**
         * 阻塞等待监视器锁。
		 *处于此状态的线程正在阻塞等待监视器锁,以进入一个同步块/方法,或者在执行完wait()方法后重入同步块/方法。
         */
        BLOCKED,

        /**
         * 等待。执行完Object.wait无超时参数操作,或者 Thread.join无超时参数操作(进入等待指定的线程执行结束),或者 LockSupport.park操作后,线程进入等待状态。
         * 一般在等待状态的线程在等待其它线程执行特殊操作,例如:等待另其它线程操作Object.notify()唤醒或者Object.notifyAll()唤醒所有。
         */
        WAITING,

        /**
         * 限时等待。
		 * Thread.sleep、Object.wait带超时时间、Thread.join带超时时间、LockSupport.parkNanos、LockSupport.parkUntil这些操作会时线程进入限时等待。
         */
        TIMED_WAITING,

        /**
         * 终止,线程执行完毕。
         */
        TERMINATED;
    }

    /**
     * 返回该线程的状态。 该方法用于监视系统状态,不用于同步控制
     */
    public State getState() {
        // get current thread state
        return sun.misc.VM.toThreadState(threadStatus);
    }

    // Added in JSR-166

    /**
     * Interface for handlers invoked when a <tt>Thread</tt> abruptly
     * terminates due to an uncaught exception.
     * <p>When a thread is about to terminate due to an uncaught exception
     * the Java Virtual Machine will query the thread for its
     * <tt>UncaughtExceptionHandler</tt> using
     * {@link #getUncaughtExceptionHandler} and will invoke the handler's
     * <tt>uncaughtException</tt> method, passing the thread and the
     * exception as arguments.
     * If a thread has not had its <tt>UncaughtExceptionHandler</tt>
     * explicitly set, then its <tt>ThreadGroup</tt> object acts as its
     * <tt>UncaughtExceptionHandler</tt>. If the <tt>ThreadGroup</tt> object
     * has no
     * special requirements for dealing with the exception, it can forward
     * the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler
     * default uncaught exception handler}.
     *
     * @see #setDefaultUncaughtExceptionHandler
     * @see #setUncaughtExceptionHandler
     * @see ThreadGroup#uncaughtException
     * @since 1.5
     */
    @FunctionalInterface
    public interface UncaughtExceptionHandler {
        /**
         * Method invoked when the given thread terminates due to the
         * given uncaught exception.
         * <p>Any exception thrown by this method will be ignored by the
         * Java Virtual Machine.
         * @param t the thread
         * @param e the exception
         */
        void uncaughtException(Thread t, Throwable e);
    }

    // null unless explicitly set
    private volatile UncaughtExceptionHandler uncaughtExceptionHandler;

    // null unless explicitly set
    private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;

    /**
     * Set the default handler invoked when a thread abruptly terminates
     * due to an uncaught exception, and no other handler has been defined
     * for that thread.
     *
     * <p>Uncaught exception handling is controlled first by the thread, then
     * by the thread's {@link ThreadGroup} object and finally by the default
     * uncaught exception handler. If the thread does not have an explicit
     * uncaught exception handler set, and the thread's thread group
     * (including parent thread groups)  does not specialize its
     * <tt>uncaughtException</tt> method, then the default handler's
     * <tt>uncaughtException</tt> method will be invoked.
     * <p>By setting the default uncaught exception handler, an application
     * can change the way in which uncaught exceptions are handled (such as
     * logging to a specific device, or file) for those threads that would
     * already accept whatever "default" behavior the system
     * provided.
     *
     * <p>Note that the default uncaught exception handler should not usually
     * defer to the thread's <tt>ThreadGroup</tt> object, as that could cause
     * infinite recursion.
     *
     * @param eh the object to use as the default uncaught exception handler.
     * If <tt>null</tt> then there is no default handler.
     *
     * @throws SecurityException if a security manager is present and it
     *         denies <tt>{@link RuntimePermission}
     *         ("setDefaultUncaughtExceptionHandler")</tt>
     *
     * @see #setUncaughtExceptionHandler
     * @see #getUncaughtExceptionHandler
     * @see ThreadGroup#uncaughtException
     * @since 1.5
     */
    public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(
                new RuntimePermission("setDefaultUncaughtExceptionHandler")
                    );
        }

         defaultUncaughtExceptionHandler = eh;
     }

    /**
     * 返回线程由于未捕获到异常而突然终止时调用的默认处理程序。如果返回值为 null,则没有默认处理程序。 
     */
    public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
        return defaultUncaughtExceptionHandler;
    }

    /**
     * 返回该线程由于未捕获到异常而突然终止时调用的处理程序。
	 * 如果该线程尚未明确设置未捕获到的异常处理程序,则返回该线程的 ThreadGroup 对象,除非该线程已经终止,在这种情况下,将返回 null。 
     */
    public UncaughtExceptionHandler getUncaughtExceptionHandler() {
        return uncaughtExceptionHandler != null ?
            uncaughtExceptionHandler : group;
    }

    /**
     * 设置该线程由于未捕获到异常而突然终止时调用的处理程序。
     * 通过明确设置未捕获到的异常处理程序,线程可以完全控制它对未捕获到的异常作出响应的方式。
     * 如果没有设置这样的处理程序,则该线程的 ThreadGroup 对象将充当其处理程序。 
     */
    public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
        checkAccess();
        uncaughtExceptionHandler = eh;
    }

    /**
     * Dispatch an uncaught exception to the handler. This method is
     * intended to be called only by the JVM.
     */
    private void dispatchUncaughtException(Throwable e) {
        getUncaughtExceptionHandler().uncaughtException(this, e);
    }

    /**
     * Removes from the specified map any keys that have been enqueued
     * on the specified reference queue.
     */
    static void processQueue(ReferenceQueue<Class<?>> queue,
                             ConcurrentMap<? extends
                             WeakReference<Class<?>>, ?> map)
    {
        Reference<? extends Class<?>> ref;
        while((ref = queue.poll()) != null) {
            map.remove(ref);
        }
    }

    /**
     *  Weak key for Class objects.
     **/
    static class WeakClassKey extends WeakReference<Class<?>> {
        /**
         * saved value of the referent's identity hash code, to maintain
         * a consistent hash code after the referent has been cleared
         */
        private final int hash;

        /**
         * Create a new WeakClassKey to the given object, registered
         * with a queue.
         */
        WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
            super(cl, refQueue);
            hash = System.identityHashCode(cl);
        }

        /**
         * 重写hashcode方法.
         */
        @Override
        public int hashCode() {
            return hash;
        }

        /**
         *重写equals方法.
         */
        @Override
        public boolean equals(Object obj) {
            if (obj == this)
                return true;

            if (obj instanceof WeakClassKey) {
                Object referent = get();
                return (referent != null) &&
                       (referent == ((WeakClassKey) obj).get());
            } else {
                return false;
            }
        }
    }




    /** The current seed for a ThreadLocalRandom */
    @sun.misc.Contended("tlr")
    long threadLocalRandomSeed;

    /** Probe hash value; nonzero if threadLocalRandomSeed initialized */
    @sun.misc.Contended("tlr")
    int threadLocalRandomProbe;

    /** Secondary seed isolated from public ThreadLocalRandom sequence */
    @sun.misc.Contended("tlr")
    int threadLocalRandomSecondarySeed;

    /* 一些私有的本地方法 */
    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);
}

原来thread本身也是Runnable的实现类。接下来再来看这个类的方法吧。在正式学习Thread类中的具体方法之前,我们先来了解一下线程有哪些状态,这个将会有助于后面对Thread类中的方法的理解。通过枚举的方式,Java在thread定义了线程的状态。

/**
     * 
     *
     * JVM中的线程必须只能是以下6种状态的一种。这些状态是JVM状态并不能和操作系统线程状态互相映射。
     */
    public enum State {
        /**
	 * 线程刚创建,还未执行(start方法)
         */
        NEW,

        /**
         * 已就绪可运行的状态。
	 * 处于此状态的线程是正在JVM中运行的,但可能在等待操作系统级别的资源,例如CPU时间片
         */
        RUNNABLE,

        /**
         * 阻塞等待监视器锁。
	 *处于此状态的线程正在阻塞等待监视器锁,以进入一个同步块/方法,或者在执行完wait()方法后重入同步块/方法。
         */
        BLOCKED,

        /**
         * 等待。执行完Object.wait无超时参数操作,或者 Thread.join无超时参数操作(进入等待指定的线程执行结束),或者 LockSupport.park操作后,线程进入等待状态。
         * 一般在等待状态的线程在等待其它线程执行特殊操作,例如:等待另其它线程操作Object.notify()唤醒或者Object.notifyAll()唤醒所有。
         */
        WAITING,

        /**
         * 限时等待。
	 * Thread.sleep、Object.wait带超时时间、Thread.join带超时时间、LockSupport.parkNanos、LockSupport.parkUntil这些操作会时线程进入限时等待。
         */
        TIMED_WAITING,

        /**
         * 终止,线程执行完毕。
         */
        TERMINATED;
    }
 

java层次的状态转换图


操作系统层次的状态转换图


创建(new)状态: 准备好了一个多线程的对象

就绪(runnable)状态: 调用了start()方法, 等待CPU进行调度

运行(running)状态: 执行run()方法

阻塞(blocked)状态: 暂时停止执行, 可能将资源交给其它线程使用

终止(dead)状态: 线程销毁

上下文切换:对于单核CPU来说(对于多核CPU,此处就理解为一个核),CPU在一个时刻只能运行一个线程,当在运行一个线程的过程中转去运行另外一个线程,这个叫做线程上下文切换.


三.Thread 学习

3.1 thread的基本属性

a)name:线程名称,可以重复,若没有指定会自动生成

b)线程ID,一个正long值,创建线程时指定,终生不变,线程终结时ID可以复用。

c)priority:线程优先级,取值为1到10,线程优先级越高,执行的可能越大,若运行环境不支持优先级分10级,如只支持5级,那么设置5和设置6有可能是一样的。

d)ThreadGroup:所属线程组,一个线程必然有所属线程组。ThreadGroup作用:

   d1)ThreadGroup可以遍历线程,知道哪些线程已经运行完毕,哪些还在运行

   d2)可以通过ThreadGroup.activeCount()知道有多少线程从而可以控制插入的线程数。

e)UncaughtExceptionHandler:未捕获异常时的处理器,默认没有,线程出现错误后会立即终止当前线程运行,并打印错误。

f)threadInitNumber:默认线程的自动编号.

3.2 thread的常量字段摘要

a)MIN_PRIORITY:1,最低优先级

b)NORM_PRIORITY:5,普通优先级

c)MAX_PRIORITY:10,最高优先级

3.3构造方法

a.无参的构造函数

   public Thread()

b.带有一个参数Runnable接口实现对象target的构造函数

    public Thread(Runnable target)

c.带有一个参数线程名name的构造函数

    Thread(String name)

d.这个不是一个公共的构造函数。

    Thread(Runnable target, AccessControlContext acc)

e.带有两个参数线程组group和线程名name的构造函数

     Thread(ThreadGroup group, String name)

f.带有两个参数Runnable接口实现对象target和线程名name的构造函数

    Thread(Runnable target, String name)

g.带有两个参数线程组group和Runnable接口实现对象target的构造函数

    Thread(ThreadGroup group, Runnable target)

h.带有三个参数线程组group、Runnable接口实现对象target、线程名name的构造函数

    Thread(ThreadGroup group, Runnable target, String name)

i.带有四个个参数线程组group、Runnable接口实现对象target、线程名name、新线程分配所需堆栈大小stackSize的构造函数

    Thread(ThreadGroup group, Runnable target, String name, long stackSize)

3.4 方法摘要

静态方法

  • Thread Thread.currentThread() :获得当前线程的引用。获得当前线程后对其进行操作。

  • Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() :返回线程由于未捕获到异常而突然终止时调用的默认处理程序。
  • int Thread.activeCount():当前线程所在线程组中活动线程的数目。
  • void dumpStack() :将当前线程的堆栈跟踪打印至标准错误流。
  • int enumerate(Thread[] tarray) :将当前线程的线程组及其子组中的每一个活动线程复制到指定的数组中。
  • Map<Thread,StackTraceElement[]> getAllStackTraces() :返回所有活动线程的堆栈跟踪的一个映射。
  • boolean holdsLock(Object obj) :当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。
  • boolean interrupted() :测试当前线程是否已经中断。
  • void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) :设置当线程由于未捕获到异常而突然终止,并且没有为该线程定义其他处理程序时所调用的默认处理程序。
  • void sleep(long millis) :休眠指定时间
  • void sleep(long millis, int nanos) :休眠指定时间
  • void yield() :暂停当前正在执行的线程对象,并执行其他线程。意义不太大

普通方法

  • void checkAccess() :判定当前运行的线程是否有权修改该线程。
  • ClassLoader getContextClassLoader() :返回该线程的上下文 ClassLoader。
  • long getId() :返回该线程的标识符。
  • String getName() :返回该线程的名称。
  • int getPriority() :返回线程的优先级。
  • StackTraceElement[] getStackTrace() :返回一个表示该线程堆栈转储的堆栈跟踪元素数组。
  • Thread.State getState() :返回该线程的状态。
  • ThreadGroup getThreadGroup() :返回该线程所属的线程组。
  • Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() :返回该线程由于未捕获到异常而突然终止时调用的处理程序。
  • void interrupt() :中断线程。
  • boolean isAlive() :测试线程是否处于活动状态。
  • boolean isDaemon() :测试该线程是否为守护线程。
  • boolean isInterrupted():测试线程是否已经中断。
  • void join() :等待该线程终止。
  • void join(long millis) :等待该线程终止的时间最长为 millis 毫秒。
  • void join(long millis, int nanos) :等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。
  • void run() :线程启动后执行的方法。
  • void setContextClassLoader(ClassLoader cl) :设置该线程的上下文 ClassLoader。
  • void setDaemon(boolean on) :将该线程标记为守护线程或用户线程。
  • void start():使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
  • String toString():返回该线程的字符串表示形式,包括线程名称、优先级和线程组。

作废方法:

  • int countStackFrames() :没有意义不做解释。
  • void destroy() :破坏线程,不释放锁,已经不能再使用,使用会抛出NoSuchMethodError。 
  • void suspend() :挂起线程,不要使用。
  • void resume() :恢复线程,不要使用。
  • void stop() :停止线程释放锁,不要使用。
  • void stop(Throwable obj) :同上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值