Java多线程 6:Thread中的静态方法

Thread 类中的静态方法快速到底

Thread 类中的静态方法表示操作的线程是 "正在执行静态方法所在的代码块的线程"。为什么 Thread 类中要有静态方法,这样就能对CPU当前正在运行的线程进行操作。下面来看一下 Thread 类中的静态方法:

1、currentThread()

currentThread() 方法返回的是对当前正在执行线程对象的引用。看一个重要的例子,然后得出结论:

public class MyThread extends Thread
{
    static
    {
        System.out.println("静态块的打印:" + Thread.currentThread().getName());    
    }
    
    public MyThread()
    {
        System.out.println("构造方法的打印:" + Thread.currentThread().getName());    
    }
    
    public void run()
    {
        System.out.println("run()方法的打印:" + Thread.currentThread().getName());
    }
    
    // 测试方法
    public static void main(String[] args)
    {
        MyThread mt = new MyThread();
        mt.start();
    }
}

运行结果

静态块的打印:main
构造方法的打印:main
run()方法的打印:Thread-0

这个例子说明了,线程类的构造方法、静态块是被 main 线程调用的,而线程类的 run() 方法才是应用线程自己调用的。在这个例子的基础上,再深入:

public class MyThread extends Thread
{
    public MyThread()
    {
        System.out.println("MyThread----->Begin");
        System.out.println("Thread.currentThread().getName()----->" + Thread.currentThread().getName());
        System.out.println("this.getName()----->" + this.getName());
        System.out.println("MyThread----->end");
    }
    
    public void run()
    {
        System.out.println("run----->Begin");
        System.out.println("Thread.currentThread().getName()----->" + Thread.currentThread().getName());
        System.out.println("this.getName()----->" + this.getName());
        System.out.println("run----->end");
    }
    
    // 测试方法
    public static void main(String[] args)
    {
        MyThread mt = new MyThread();
        mt.start();
    }
}

运行结果

MyThread----->Begin
Thread.currentThread().getName()----->main
this.getName()----->Thread-0
MyThread----->end run----->Begin Thread.currentThread().getName()----->Thread-0 this.getName()----->Thread-0 run----->end

上篇文章的开头就说过,要理解一个重要的概念,就是 "this.XXX()" 和 "Thread.currentThread().XXX()" 的区别,这个就是最好的例子。必须要清楚的一点就是:当前执行的 Thread 未必就是 Thread 本身。从这个例子就能看出来:

(1)执行 MyThread 构造方法是 main,当前线程却是 Thread-0

(2)执行 run() 方法的 Thread-0,当前线程也是 Thread-0,说明 run() 方法就是被线程实例去执行的

所以,再强调一下,未必在 MyThread 里调用 Thread.currentThread() 返回回来的线程对象的引用就是 MyThread

2、sleep(long millis)

sleep(long millis) 方法的作用是在指定的毫秒内让当前"正在执行的线程"休眠(暂停执行)。这个"正在执行的线程"是关键,指的是 Thread.currentThread() 返回的线程。根据J DK API 的说法,"该线程不丢失任何监视器的所属权",简单说就是 sleep 代码上下文如果被加锁了,锁依然在,但是 CPU 资源会让出给其他线程。例子就不写了,很简单。

3、yield()

暂停当前执行的线程对象,并执行其他线程。这个暂停是会放弃 CPU 资源的,并且放弃 CPU 的时间不确定,有可能刚放弃,就获得 CPU 资源了,也有可能放弃好一会儿,才会被 CPU 执行。看一下例子:

public class MyThread extends Thread
{
    public void run()
    {
        long beginTime = System.currentTimeMillis();
        int count = 0;
        for (int i = 0; i < 50000000; i++)
        {
            Thread.yield();
            count = count + i + 1;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("count:"+count);
        System.out.println("用时:" + (endTime - beginTime) + "毫秒!");
    }
    // 测试方法
    public static void main(String[] args)
    {
        MyThread mt = new MyThread();
        System.out.println("begin = " + System.currentTimeMillis());
        mt.start();
        
        System.out.println("end = " + System.currentTimeMillis());
    }
}

运行结果

begin = 1524485060250
end = 1524485060251
count:1333106752
用时:6249毫秒!
----------------------------
begin = 1524485136599
end = 1524485136600
count:1333106752
用时:6447毫秒!

----------------------------
begin = 1524485162837
end = 1524485162837
count:1333106752
用时:6234毫秒!

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

4、interrupted()

测试当前线程是否已经中断,执行后具有将状态标识清除为 false 的功能。换句话说,如果连续两次调用该方法,那么返回的必定是 false:

public static void main(String[] args)
{
    Thread.currentThread().interrupt();
    System.out.println("是否停止1?" + Thread.interrupted());
    System.out.println("是否停止2?" + Thread.interrupted());
    System.out.println("end!");
}

当然,这也涉及 Java 的中断机制,留在后面的一篇文章专门讲解。

猜你喜欢

转载自www.cnblogs.com/tkzL/p/8921503.html