Java多线程编程-Thread API (一)


Thread是Java实现多线程的关键类,Thread提供了先关的API,我们来说说相关的API,就从我们使用最多的开始说起。

Thread.currentThread()

currentThread():返回对当前正在执行的线程对象的引用
源码:

//调用native的方法
public static native Thread currentThread();

我们都知道,Java的程序主入口是main方法,会默认启动一个Main线程进行运行,如下代码:

public class ThreadApiCurrentThreadV1 {

    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName());
    }

}

运行结果
在这里插入图片描述
我们知道Thread会实现Runnable接口的run()方法,我们启动一个线程是使用start()方法。
我们看看run()方法和start()方法他们调用的线程就是是哪一个线程?上代码:

public class ThreadApiCurrentThreadV2 extends Thread {
    public ThreadApiCurrentThreadV2() {
        System.out.println("current thread name:" + Thread.currentThread().getName());
    }
    @Override
    public void run() {
        System.out.println("current thread name:" + Thread.currentThread().getName());
    }
}

运行代码:

public class ThreadApiCurrentThreadV2Main {
    public static void main(String[] args) {
        ThreadApiCurrentThreadV2 threadApiCurrentThreadV2 = new ThreadApiCurrentThreadV2();
        threadApiCurrentThreadV2.run();
    }
}

运行结果为:
在这里插入图片描述
由上面的运行可以看出,构造ThreadApiCurrentThreadV2 的是主线程main,调用run()方法也是main方法,由此可以得到在运行线程的时候,不会另开一个线程去运行,就和普通的类方法一样。
我们使用jconsole也可以看出,如图
在这里插入图片描述
只有一个main线程。
运行start()方法,看看运行结果
在这里插入图片描述
现在会有一个新的线程为Thread-0,我们来看看jconsole的线程
在这里插入图片描述
会有一个新的Thread-0的线程在运行
由此可以得出结论:
1.java运行的时候,会有一个主线程main
2.在调用Thread的run方法时,不会创建一个新的线程去执行,就相当于普通对象调用方法一样
3.在调用Thread的start方法时,才会创建一个新的线程去执行run方法中的代码块

Thread.isAlive()方法

isAlive():测试此线程是否仍然存在。如果线程已经启动但尚未死亡,则该线程是活动的
源码:

public final native boolean isAlive();

在进行多线程的情况下,代码的顺序不会按照顺序执行,线程的运行是随机(获取CPU的执行权)

public class ThreadIsAliveV1 extends Thread {
    @Override
    public void run() {
        System.out.println("this is a test alive api");
    }
}

运行如下代码:

public class ThreadIsAliveV1Main {
    public static void main(String[] args) {
        ThreadIsAliveV1 threadIsAliveV1 = new ThreadIsAliveV1();
        System.out.println("threadIsAliveV1 is alive:" + threadIsAliveV1.isAlive());
        threadIsAliveV1.start();
        System.out.println("threadIsAliveV1 is alive:" + threadIsAliveV1.isAlive());
    }
}

运行结果:
在这里插入图片描述
这里第二句输出也true,但是这行代码是start()方法之后运行的啊?怎么还在活动状态呢?这个值是不确定的,有可能执行完了,也有可能没有执行完。
我们可以将主线程睡眠10秒看看结果,start()方法添加如下代码:

Thread.sleep(10000);

在看看結果:
在这里插入图片描述
这里讲会得到false,说明线程已经执行完成了。执行如图所示:
在这里插入图片描述

Thread.sleep()方法

sleep():根据系统计时器和调度程序的精度和准确性,使当前正在执行的线程进入休眠状态(暂时停止执行)达指定的毫秒数。该线程不会失去任何监视器的所有权。
源码:

public static native void sleep(long millis) throws InterruptedException;

我们通过调用run方法和start方法进行测试sleep方法
调用run方法:

public class ThreadSleepApiV1 extends Thread {
    @Override
    public void run() {
        try {
            System.out.println("current thread:" + this.currentThread().getName());
            Thread.sleep(2000);
            System.out.println("end current thread:" + this.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行代码:

public class ThreadSleepApiV1Main {
    public static void main(String[] args) {
        ThreadSleepApiV1 threadSleepApiV1 = new ThreadSleepApiV1();
        System.out.println("start timestamp:" + System.currentTimeMillis());
        threadSleepApiV1.run();
        System.out.println("end timestamp:" + System.currentTimeMillis());
    }
}

运行结果:
在这里插入图片描述
上面的时间是同步的运行的,相隔2000毫秒。
调用start方法:

public class ThreadSleepApiV2 extends Thread {
    @Override
    public void run() {
        try {
            System.out.println("current thread:" + this.currentThread().getName() + ",begin time:" + System.currentTimeMillis());
            Thread.sleep(2000);
            System.out.println("end current thread:" + this.currentThread().getName() + ",end time:" + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行代码:

public class ThreadSleepApiV1Main {

    public static void main(String[] args) {
        ThreadSleepApiV2 threadSleepApiV2 = new ThreadSleepApiV2();
        System.out.println("start timestamp:" + System.currentTimeMillis());
        threadSleepApiV2.start();
        System.out.println("end timestamp:" + System.currentTimeMillis());
    }
}

运行结果:
在这里插入图片描述
由运行结果可以看出,main和Thread-0是异步运行的,先输入了main线程中的时间,在输出Thread-0执行run的时间。

Thread.getId()方法

getId():返回此线程的标识符。线程ID是创建该线程时生成的正long型数。线程ID是唯一的,并且在其生命周期内保持不变。当线程终止时,可以重新使用该线程ID。
源码:

public long getId() {
    return tid;
}

现在在创建的时候,就会对id进行设置,是通过一个同步的方法进行,同步的方法为:

private static synchronized long nextThreadID() {
    return ++threadSeqNumber;
}

我们创建两个线程看看获取的id变化

public class ThreadIdV1 extends Thread {

    @Override
    public void run() {
        System.out.println("id v1");
    }
}

public class ThreadIdV2 extends Thread {

    @Override
    public void run() {
        System.out.println("id v2");
    }

}

运行代码:

public class ThreadIdVMain {

    public static void main(String[] args) {
        ThreadIdV1 threadIdV1 = new ThreadIdV1();
        System.out.println(threadIdV1.getId());
        threadIdV1.start();
        ThreadIdV2 threadIdV2 = new ThreadIdV2();
        System.out.println(threadIdV2.getId());
        threadIdV2.start();
    }
}

运行结果:
在这里插入图片描述
main线程的id为1,可以在运行代码加入代码

System.out.println(Thread.currentThread().getId());

将输出1.

总结

1.调用currentThread()方法在线程中引入线程的话,Thread.currentThread()和this所获取会有所差异,可以实验一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值