多线程基础二、currentThread()、isAlive()、sleep()、getId()

来源:互联网 发布:移动台开户数据 编辑:程序博客网 时间:2024/03/28 21:25
本节主要介绍线程的方法:currentThread()、isAlive()、sleep()、getId()
1. currentThread() 方法:返回代码段正在被哪个线程调用
例1:
/** * @ClassName GetThreadName * @Description 获取正在被哪个线程调用 */public class GetThreadName {    public static void main(String[] args) {        System.out.println(Thread.currentThread().getName());    }    /*    运行结果:说明 main 方法被名为 main 的线程调用    main     */}
例2:
/** * @ClassName MyThread * @Description 线程 构造函数和run方法分别输出调用者 */public class MyThread extends Thread {    public MyThread() {        System.out.println("构造方法被:" + Thread.currentThread().getName() + " 调用");    }    @Override    public void run() {        System.out.println("run方法被:" + Thread.currentThread().getName() + " 调用");    }}
/** * @ClassName MyThreadTest * @Description 测试start() 和 run() 方法的实际调用者 */public class MyThreadTest {    public static void main(String[] args) {        MyThread myThread = new MyThread();        //1-调用start() 方法        myThread.start();        /*        运行结果:        构造方法被:main 调用        run方法被:Thread-0 调用         */        //2-调用run() 方法        //myThread.run();        /*        运行结果:        构造方法被:main 调用        run方法被:main 调用         */    }}
结果显示: 线程的 构造函数是被 main 线程调用的,而 线程中 run() 方法是线程自动调用
例3:
public class MyThread2 extends Thread {    public MyThread2() {        System.out.println("Constructor --- begin");        System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());        System.out.println("this.getName() = " + this.getName());        System.out.println("Constructor --- end");    }    @Override    public void run() {        System.out.println("-------------------------------------------");        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 class MyThread2Test {    public static void main(String[] args) {        MyThread2 myThread2 = new MyThread2();        Thread t1 = new Thread(myThread2);        t1.setName("AAA");        t1.start();    }    /*    运行结果:    Constructor --- begin    Thread.currentThread().getName() = main    this.getName() = Thread-0    Constructor --- end    -------------------------------------------    run --- begin    Thread.currentThread().getName() = AAA    this.getName() = Thread-0    run --- end     */}

2. isAlive() 方法:判断当前线程是否处于活动状态。活动状态指 线程已经启动且尚未终止。线程处于正在运行或者准备开始运行的状态,则认为线程是"存活"的
public class MyThread extends Thread {    @Override    public void run() {        System.out.println("run=" + this.isAlive());    }}
public class Run {    public static void main(String[] args) throws InterruptedException {        MyThread myThread = new MyThread();        System.out.println("begin == " + myThread.isAlive());        myThread.start();        //Thread.sleep(1000);        System.out.println("end == " + myThread.isAlive());        /*        运行结果:        1. 没有sleep        begin == false        end == true        run=true        2. 有sleep        begin == false        run=true        end == false         */    }}
需要说明一下的是:System.out.println("end == " + myThread.isAlive()); 输出的值是不确定的。因为在程序最后该线程可能已经执行完了,或者没有执行完。
如果加上sleep() 方法,那么线程已经运行完,所以输出 end == false。
例2:
/** * @ClassName MyThread2 * @Description 测试 Thread.currentThread 和 this 的区别 */public class MyThread2 extends Thread {    public MyThread2() {        System.out.println("Constructor --- begin");        System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());        System.out.println("Thread.currentThread().isAlive() = " + Thread.currentThread().isAlive());        System.out.println("this.getName() = " + this.getName());        System.out.println("this.isAlive() = " + this.isAlive());        System.out.println("Constructor --- end");    }    @Override    public void run() {        System.out.println("-------------------------------------------");        System.out.println("run --- begin");        System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());        System.out.println("Thread.currentThread().isAlive() = " + Thread.currentThread().isAlive());        System.out.println("this.getName() = " + this.getName());        System.out.println("this.isAlive() = " + this.isAlive());        System.out.println("run --- end");    }}
public class Test2 {    public static void main(String[] args) {        MyThread2 mt = new MyThread2(); // 1        Thread t1 = new Thread(mt); //2        System.out.println("main begin t1 isAlive = " + t1.isAlive());        t1.setName("AAA"); //3        t1.start(); //4        System.out.println("main end t1 isAlive = " + t1.isAlive());    }    /*    运行结果:    Constructor --- begin    Thread.currentThread().getName() = main    Thread.currentThread().isAlive() = true    this.getName() = Thread-0    this.isAlive() = false    Constructor --- end    main begin t1 isAlive = false    main end t1 isAlive = true    -------------------------------------------    run --- begin    Thread.currentThread().getName() = AAA    Thread.currentThread().isAlive() = true    this.getName() = Thread-0    this.isAlive() = false    run --- end     */}
这里说明一下:步骤1,main方法实例化 MyThread2 类,所以是由 main 线程调用的 MyThread2 构造方法。上半部分结果中的 Thread.currentThread() 指的就是 main 线 程,Thread.currentThread().getName() = main,此时 main 线程是活动的,即 Thread.currentThread().isAlive() = true。而在构造方法中 this 指的是 MyThread2 这个对 象,那么为什么 this.getName() = Thread-0 呢?我们看一下 Thread 源码:

 Thread-0 是 线程在初始化时设置的,所以 this.getName() = Thread-0。此时 MyThread2 线程并没有 start(),所以 this.isAlive() = false。
步骤2、3、4:步骤2中创建了一个新线程并将之前创建的 MyThread2 线程对象作为 target 传入 t1,此时 t1 的 run() 方法其实是调用 target.run(),即调用的是 MyThread2 的 run() 方法。run() 方法中 this 指的是 MyThread2 而不是 t1Thread.currentThread() 在 t1.start() 之后就是 t1了,所以  Thread.currentThread().getName() = AAA,Thread.currentThread().isAlive() = true。而this.getName() = Thread-0 ,this.isAlive() = false。
3. sleep() 方法:在指定的毫秒数内让当前“正在执行的线程”休眠,“正在执行的线程”指 this.currentThread() 返回的线程
public class MyThread extends Thread {    @Override    public void run() {        try {            System.out.println("run threadName = " + this.currentThread().getName() + " begin");            Thread.sleep(2000);            System.out.println("run threadName = " + this.currentThread().getName() + " end");        } catch (InterruptedException e) {            e.printStackTrace();        }    }}       
public class Test {    public static void main(String[] args) {        MyThread myThread = new MyThread();        long beginTime = System.currentTimeMillis();        System.out.println("begin = " + beginTime);        myThread.run(); //运行结果1//        myThread.start(); //运行结果2        long endTime = System.currentTimeMillis();        System.out.println("end = " + endTime + " , use time = " + (endTime - beginTime));        /*        运行结果1:main线程直接调用 run() 方法,所以 sleep()也是main线程,总共用时2s多        begin = 1502868769857        run threadName = main begin        run threadName = main end        end = 1502868771887 , use time = 2030        运行结果2:main线程 和 myThread 线程同时执行,main 线程统计时间,而myThread 中间暂停了2s        begin = 1502869043441        end = 1502869043442 , use time = 1        run threadName = Thread-0 begin        run threadName = Thread-0 end         */    }}
4.getId():取得线程的唯一标识。
public class MyThread extends Thread {    @Override    public void run() {        System.out.println(this.currentThread().getName() + " --- getId() = " + this.currentThread().getId());    }}
public class Test {    public static void main(String[] args) {        Thread mainThread = Thread.currentThread();        System.out.println(mainThread.getName() + " --- getId() = " + mainThread.getId());        MyThread myThread = new MyThread();        myThread.start();        /*        运行结果:        main --- getId() = 1        Thread-0 --- getId() = 10         */    }}






阅读全文
0 0