线程名
当创建一个线程的时候,如果我们不给线程明确的起一个名字的话,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和操作系统一起决定了线程的执行顺序,他和线程的启动顺序并非一定是一致的。