黑马程序员技术交流社区
标题:
【上海校区】Java多线程(三)- 线程的唯一标识(ID)是什...
[打印本页]
作者:
不二晨
时间:
2018-10-9 09:37
标题:
【上海校区】Java多线程(三)- 线程的唯一标识(ID)是什...
数据库里头,我们建表的时候通常唯一标识叫ID,Thread对象也有ID,可以通过getId来获取。这个ID是自增长的,我们可以查看Thread源代码,下面是我截取出来的代码片段。
public class Thread implements Runnable { /* For generating thread ID */ private static long threadSeqNumber; private static int threadInitNumber; private static synchronized long nextThreadID() { return ++threadSeqNumber; } private static synchronized int nextThreadNum() { return threadInitNumber++; }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
从代码中可以看到有两种ID,分别是threadSeqNumber和threadInitNumber。我来稍微解释一下,
threadSeqNumber是线程的ID
,可以看到这个ID是同步递增的,我们可以在Thread的init方法中看到,每个线程都会分配一个这样的ID。
private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) { // 此处省略其它源码 /* Set thread ID */ tid = nextThreadID();}
1
2
3
4
5
6
7
1
2
3
4
5
6
7
而threadInitNumber是当我们没有给线程起名字的时候,默认会采用Thread-N的格式给线程起名,这里的N就是threadInitNumber。从Thread源码中我们可以看到下面的构造函数,这里只列出来两个与之相关的构造。
public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0);}public Thread(String name) { init(null, null, name, 0);}
1
2
3
4
5
6
1
2
3
4
5
6
很明显,我们可以发现,如果我们采用这里无参构造,会产生一个格式为Thread-N的默认名称,此时threadInitNumber也会随之递增,如果我们采用有参的构造,threadInitNumber就不会递增。所以我们不要愚蠢的看到默认名称后面的数字,就认为我们当前主线程下开启了这么多个线程,更不要愚蠢的认为这个数字就是线程的ID。这个数字跟ID和线程数没半毛钱关系的。
当我们拿到线程的ID以后,就可以根据ID获取到这个线程对象。
如下:
public static void main(String[] args) throws Exception { // 构造一个线程并启动,取名为"my-thread" Thread myThread = new Thread(new Runnable() { public void run() { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }, "my-thread"); myThread.start(); long myThreadId = myThread.getId(); System.out.println("my-thread线程ID为:" + myThreadId); // 拿到当前线程下所有子线程,找出名称为"my-thread"的线程并输出该线程的ID // 这串代码用到了activeCount和enumerate方法,在API的介绍中有详细说明 Thread[] ts = new Thread[Thread.activeCount()]; Thread.enumerate(ts); for(Thread t: ts) { if(t.getId() == myThread.getId()) { System.out.println("从主线程中找到名为my-thread的线程,线程名称为:" + t.getName() + ", 状态为: " + t.getState()); } }}
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
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
找遍了Thread的静态方法,没有找到可以直接通过ID或者NAME去获取thread对象,最终所以采用了这种愚蠢的方式。我想说的是,无论这种方式是否最佳,但我根据ID拿到了子线程对象进而可以操作这个子线程。
注意,Thread.enumerate只能拿到非NEW和非TERMINATED状态的子线程。所以这段代码可能没有任何输出。
最后总结一下:
threadSeqNumber是线程的ID,可以通过线程对象的getId方法来获取。
(完)
【转载】
https://blog.csdn.net/u012627861 ... 600?utm_source=copy
作者:
不二晨
时间:
2018-10-10 11:27
奈斯
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2