线程名
当创建一个线程的时候,如果我们不给线程明确的起一个名字的话,JVM默认会给其指定一个默认的名字。当然我们明确的可以给线程起一个名字。它有助于我们区分不同的线程,这在我们查看线程运行时的状况会很有用。例如:如果有多个线程写入System.out,我们就能够通过线程名容易的找出是哪个线程正在输出。例子如下:
public class ThreadNameDemo { public static void main(String[] args) { //打印主线程的名称 System.out.println("主线程名称:"+Thread.currentThread().getName()); //创建一个线程,不指定名字,JVM会自动给其分配一个名字 new Thread(){ @Override public void run() { //如果运行时代码本身就是在一个线程对象中实现,那么我们可以通过this.getName获取其名称 System.out.println("JVM自动分配的线程名:"+this.getName()); } }.start(); //创建一个名字为new Thread的线程并启动 new Thread(new MyRunable(),"new Thread").start(); } static class MyRunable implements Runnable{ @Override public void run() { //如果我们编写的只是运行时代码,那么要获取将会执行这段运行时代码的线程的信息,通过Thread.currentThread()的方式 System.out.println("执行这段运行时代码的线程名:"+Thread.currentThread().getName()); } } }
这段代码的输出内容如下
主线程方法名称:main JVM自动分配的线程名:Thread-0 执行这段运行时代码的线程名:new Thread |
分析如下:
主线程的名字是就是main,这是固定的。实时上,除了主线程,还有其他线程的名字也是固定的,例如垃圾回收线程的名字是:Finalizer
,信号转发器线程名是Signal Dispatcher
等。在java程序启动至少会启动几个线程这一节列出了一些JVM默认启动的线程的名字,建议读者将线程的名字都记住。
JVM自动给线程命名的策略:如果没有明确的线程指定名字,JVM就会以Thread为前缀,按照线程创建的顺序,给其命名,例如我们上面看到的"Thread-0",当然如果你还创建一个没有起名字的线程,那么其名称就是"Thread-1",...。
获取当前正在执行的线程的名称有两种方式:如果运行时代码是直接覆盖Thread类的run方法编写的,可以通过this.getName()的方式获取线程的名字;如果只是实现了Runable接口,可以通过Thread.currentThread().getName()的方式获取。
线程代码举例:
这里是一个小小的例子。首先输出执行main()方法线程名字。这个线程JVM分配的。然后开启10个线程,命名为1~10。每个线程输出自己的名字后就退出。
public class ThreadExample { public static void main(String[] args){ System.out.println(Thread.currentThread().getName()); for(int i=0; i<10; i++){ new Thread("" + i){ public void run(){ System.out.println("Thread: " + getName() + "running"); } }.start(); } } }
需要注意的是,尽管启动线程的顺序是有序的,但是执行的顺序并非是有序的。也就是说,1号线程并不一定是第一个将自己名字输出到控制台的线程。这是因为线程是并行执行而非顺序的。Jvm和操作系统一起决定了线程的执行顺序,他和线程的启动顺序并非一定是一致的。