zoukankan      html  css  js  c++  java
  • Java多线程

    原文地址:https://blog.csdn.net/u012627861/article/details/82904600

    结论

    threadSeqNumber是线程的ID,可以通过线程对象的getId方法来获取。

    分析

    数据库里头,我们建表的时候通常唯一标识叫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

    从代码中可以看到有两种ID,分别是threadSeqNumberthreadInitNumberthreadSeqNumber是线程的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

    而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

    很明显,我们可以发现,如果我们采用这里无参构造,会产生一个格式为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

    找遍了Thread的方法,没有找到可以直接通过ID或者NAME去获取thread对象的方法,最终采用了这种拙劣的方式。无论这种方式是否最佳,我们根据ID拿到了子线程对象进而可以操作这个子线程。

    注意,Thread.enumerate只能拿到非NEW和非TERMINATED状态的子线程。所以这段代码可能没有任何输出。

    (完)

     
  • 相关阅读:
    mysql引擎简介
    spring mvc + mybatis 框架搭建 ( idea + gradle)
    ubuntu下 java、mysql、tomcat(ssl认证) 配置
    Zookeeper 选举机制和脑裂问题
    mininet 入门引导
    Mac OS X 使用python urllib 模块 通过ssl访问报错 urllib.error.URLError
    macOS 下,连接zookeeper等java软件加载较慢的解决方案
    探索学习LinkedList和ArrayList的差别
    mininet 部署记录
    分布式系统 学习笔记
  • 原文地址:https://www.cnblogs.com/huanghongbo/p/13703899.html
Copyright © 2011-2022 走看看