• java 多线程3:Thread类中的静态方法


    Thread类中的静态方法

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

    1、currentThread()

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

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

    看一下运行结果:

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

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

    public class MyThread05 extends Thread
    {
        public MyThread05()
        {
            System.out.println("MyThread5----->Begin");
            System.out.println("Thread.currentThread().getName()----->" + 
                    Thread.currentThread().getName());
            System.out.println("this.getName()----->" + this.getName());
            System.out.println("MyThread5----->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)
    {
        MyThread05 mt5 = new MyThread05();
        mt5.start();
    }

    看一下运行结果:

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

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

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

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

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

    2、sleep(long millis)

    sleep(long millis)方法的作用是在指定的毫秒内让当前"正在执行的线程"休眠(暂停执行)。这个"正在执行的线程"是关键,指的是Thread.currentThread()返回的线程。根据JDK API的说法,"该线程不丢失任何监视器的所属权",直白点讲,就是不让出CPU资源。CPU还在执行当前线程run()方法中的代码,sleep不会放开锁,无非执行的内容是"睡觉"而已。看一下例子:

    public class MyThread07 extends Thread
    {
        public void run()
        {
            try
            {
                System.out.println("run threadName = " + 
                        this.getName() + " begin");
                Thread.sleep(2000);
                System.out.println("run threadName = " + 
                        this.getName() + " end");
            } 
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args)
    {
        MyThread07 mt = new MyThread07();
        System.out.println("begin = " + System.currentTimeMillis());
        mt.start();
        System.out.println("end = " + System.currentTimeMillis());
    }

    看一下运行结果:

    begin = 1443694780609
    end = 1443694780609
    run threadName = Thread-0 begin
    run threadName = Thread-0 end

    当然,因为打印结果是静态的,所以只能看出异步执行的效果,看不出sleep(long millis)方法执行的效果。实际上第3句打出2秒后打出第4句,这和run()方法里面的sleep(2000)是对应的

    3、yield()

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

    public class MyThread08 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("用时:" + (endTime - beginTime) + "毫秒!");
        }
    }
    public static void main(String[] args)
    {
        MyThread08 mt = new MyThread08();
        mt.start();
    }

    看一下运行结果:

    用时:3264毫秒!
    用时:3299毫秒!
    用时:3232毫秒!
    用时:3256毫秒!
    用时:3283毫秒!
    用时:3504毫秒!
    用时:3378毫秒!

    看到,每次执行的用时都不一样,证明了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 多线程5: java 终止线程及中断机制 (stop()、interrupt() 、interrupted()、isInterrupted())

    java 多线程6: 中断机制 优雅的终止java线程




  • 相关阅读:
    POJ 1548 Robots(最小路径覆盖)
    <html>
    站点开发-日志-1
    JSP入门实战下
    rancher官方资源
    window10死机
    window10桌面图标空白
    sentry使用docker-compose部署
    docker下一步步部署sentry
    docker-compose编排服务
  • 原文地址:https://www.cnblogs.com/signheart/p/2ef57fe11fa280453a00a48174c8be45.html
Copyright © 2020-2023  润新知