2. Thread 中的方法

一、静态方法

1.1 currentThread() 方法

currentThread() 方法返回代码段正在被哪个线程调用的那个线程的信息

public class MyThread7 extends Thread{

    static {
        System.out.println("静态代码块:" + Thread.currentThread().getName());
    }

    public MyThread7() {
        System.out.println("构造方法的打印: " + Thread.currentThread().getName());
        System.out.println("this.name(): " + this.getName());
    }

    @Override
    public void run() {
        System.out.println("run方法的打印: " + Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        MyThread7 thread = new MyThread7();
        thread.start();
        
        //语句1
//      thread.run();
    }

}

结果是:

静态代码块:main
构造方法的打印: main
this.name(): Thread-0
run方法的打印: Thread-0

可以看到,该类的构造方法和静态代码块都是被 main 线程所调用的,因此输出 main;而 this.name() 代表的是线程实例本身,此时的线程实例已经变成 Thread-0 了,因此输出 Thread-0;而 run 方法就是被新创建的线程 Thread-0 通过 start 方法调用的,因此也是输出 Thread-0

这里需要弄清楚两个概念

  • Thread.currentThread().getName():代表代码段正在被哪个线程调用的那个线程的信息
  • this.getName():表示创建的线程实例本身

对于上面那段代码,如果使用语句1,结果是

静态代码块:main
构造方法的打印: main
this.name(): Thread-0
run方法的打印: main

可以看到,对于静态代码块和构造函数,都是 main,同时,this.name() 由于新创建了一个 Thread-0 线程,因此输出也是 Thread-0

和上面唯一的区别在于 run 方法里面输出的是 main,说明虽然创建了 Thread-0 线程,但是由于没有调用 start 方法,因此新的线程没有被启动,还是处于就绪状态。此时还是用 main 线程调用的 run 方法,相当于还是同步执行的

1.2 sleep() 方法

sleep() 的作用是在指定的毫秒数内让当前“正在执行的线程”休眠,即暂停执行,这个“正在执行的线程”指的是 this.currentThread() 返回的线程

1.3 yield() 方法

yied() 方法的作用是放弃当前的 CPU 资源,将它让给其他的任务去占用 CPU 执行时间,但是放弃的时间不确定,有可能刚刚放弃,马上又获得 CPU 时间片

public class MyThread3 extends Thread {

    @Override
    public void run() {
        long beginTime = System.currentTimeMillis();
        int count = 0;
        for (int i = 0; i < 100000; i++) {
            Thread.yield();
            count = count + (i + 1);
        }

        long endTime = System.currentTimeMillis();
        System.out.println("count:" + count);
        System.out.println("用时:" + (endTime - beginTime) + " ms! ");
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread3 thread = new MyThread3();
        thread.start();
    }
}

结果:

count:705082704
用时:80 ms!
count:705082704
用时:56 ms! 
count:705082704
用时:59 ms! 
count:705082704
用时:150 ms! 
count:705082704
用时:60 ms! 
count:705082704
用时:68 ms! 

可以看到,每次执行的时间都不一样,yield()方法放弃CPU的时间并不确定。

二、实例方法

2.1 isAlive() 方法

isAlive() 方法的功能是判断当前线程是否处于活动状态

活动状态就是线程已经启动(start)且尚未终止。线程处于正在运行(调用了run)或者准备开始运行的状态,就认为线程是存活的

public class MyThread8 extends Thread {

    @Override
    public void run() {
        System.out.println("run=" + this.isAlive());
    }

    public static void main(String[] args) {
        MyThread8 thread = new MyThread8();
        System.out.println("begin == " + thread.isAlive());
        thread.start();
        System.out.println("end == " + thread.isAlive());
    }
}

结果是:

begin == false
run = true
end == true

第一个由于处于新建状态,还没有调用 start 方法启动,因此不是处在活动状态

第二个因为在 run 方法中,说明已经启动了,且处于运行状态,因此也是处于活动状态

第三个因为线程还没有终止,此时线程还是处于活动状态

但是,如果使用下面这种形式

public static void main(String[] args) throws InterruptedException {
    MyThread8 thread = new MyThread8();
    System.out.println("begin == " + thread.isAlive());
    thread.start();
    Thread.sleep(1000);
    System.out.println("end == " + thread.isAlive());
}

结果是:

begin == false
run = true
end == false

因为此时使用 Thread.sleep(1000) 方法使得当前执行的线程暂停执行,即被终止,因此输出 false

2.2 getId() 方法

getId() 方法的作用是取得线程的唯一标识

public class MyThread10 extends Thread{

    public static void main(String[] args) {
        MyThread10 thread0 = new MyThread10();
        System.out.println(thread0.getName() + " " + thread0.getId());

        Thread threadmain = Thread.currentThread();
        System.out.println(threadmain.getName() + " " + threadmain.getId());
    }

}

结果是:

Thread-0 11
main 1

线程 Thread-0 的名称是 main,线程 id 是 11;线程 main 的名称是 main,线程 id 是 1

2.3 setDaemon() 方法

对于 Java 程序来说,只要还有一个前台线程在运行,那么这个进程就不会结束,如果一个进程中只有后台进程在运行,那么这个进程就会结束。

那么什么是后台进程呢?如果某个线程对象在启动(start()方法)之前调用了 setDaemon() 方法,那么这个线程就变成了后台线程

public class ThreadTest4 extends Thread {

    @Override
    public void run() {
        while (true) {
            System.out.println(Thread.currentThread().getName() + "is running");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        //创建线程 Thread-0
        ThreadTest4 threadTest4 = new ThreadTest4();
        //设置 Thread-0 在后台运行,此时线程 Thread-0 就是后台进程
        threadTest4.setDaemon(true);
        //启动线程 Thread-0
        threadTest4.start();
        //这里把CPU让给线程 Thread-0 一秒钟
        Thread.sleep(1000); //语句1
    }
}

结果:

Thread-0is running
Thread-0is running
Thread-0is running
Thread-0is running
Thread-0is running
Thread-0is running
Thread-0is running
Thread-0is running

控制台会在1s之内打印这些语句然后停止,如果将语句1注释掉,那么控制台不会打印

可以看到,该进程中有两个进程 main 和 Thread-0,其中 main 是主线程,Thread-0 在设置后变成了后台进程。在线程 main 执行完之后,线程中就只剩下后台进程 Thread-0,而如果一个进程中只有后台进程,此进程就会结束,此时就停止打印

三、参考

《Java多线程编程核心技术》
https://www.cnblogs.com/xrq730/p/4851233.html

猜你喜欢

转载自blog.csdn.net/babycan5/article/details/83246719