java thread 源代码_Java多线程学习(一)——Thread类源码

概述

创建线程的方法常用的有两种,一个是继承Thread类,另一个是实现Runnable接口,然后用Runnable对象创建Thread类。所以在日常使用过程中,不可避免的使用Thread类,本文通过查看Thread类源码的方式,查看Thread类的方法,以及方法的实现原理。

构造方法

自己阅读源码的方式通常是从构造方法看起,里面会进行一些成员变量的初始化,有些是值得注意的。

无参构造

为什么默认的线程名会使用Thread-x,这里就说明了为什么。

f78b7bf312bd6db58891b2edca077a7c.png

Runnable参数

使用Runbable对象创建线程时,会使用target参数。

500ae3c7fbb7a5bfed9dc5af22e478b5.png

Runnable参数+String参数

这里的String用来给线程命名。

8c088af618c02d77706ce8a277564a60.png

其他构造方法

ff084d5db60252d831b866d4c8eb918d.png

76213a0a9b7205aeff9e3a491d2a977d.png

8c9480c74bf332680e7109c307cd760d.png

等等,这里不列举全了。

start()方法和run()方法的区别

根据文档介绍,这个方法的执行结果是会用两条线程同时运行。且不可以调用一个线程两次start方法。

b06980e5760b1356b48044f52c85fddb.png

run方法针对的是传入的Runnable对象,调用Runnable的run方法。那么可以看出,run方法并不会开辟一个新的线程,而只是运行run的方法体。所以总结来说,在启动线程的时候,需要使用start方法启动。

363be5657ad610746e9e3db61e6a59fd.png

yield()方法和join()方法

yield()方法 暂停当前正在执行的线程对象,并执行其他线程。

官方翻译:给调度器一个提示,当前线程愿意让出占用的处理器。调度器可以忽略这个提示。

yield方法是一种启发式尝试(大雾),用于改善线程之间的相对进展,否则会过度利用CPU。 它的使用应与详细的分析和基准测试相结合,以确保它实际上具有所需的效果。

很少场景适合使用这个方法。 它可能对调试或测试目的很有用,它可能有助于重现因竞争条件而产生的错误。 在设计并发控制结构(例如java.util.concurrent.locks包中的结构)时,它也可能很有用。

4edad7363d52405cbebcc8ec93ec0ab2.png

yield()方法实例

class Run implements Runnable{

public static volatile boolean flag = true;

@Override

public void run() {

String name = Thread.currentThread().getName();

System.out.println(name + "开始执行");

while (flag){

for (int i = 0; i < 6; i++) {

System.out.println(Thread.currentThread().getName() + "执行了" + i + "次");

Thread.yield();

}

}

System.out.println(name + "执行完毕");

}

}

public class Entry2 {

public static void main(String[] args) {

Thread t1 = new Thread(new Run());

Thread t2 = new Thread(new Run());

t1.start();

t2.start();

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

Run.flag = false;

}

}

实行结果

效果就是两个线程因为yield方法交替执行。

4285fb07b7613cdc2287c97bf711dbdf.png

yield的使用场景

yield的作用就是暂时让出使用着的CPU,这样其他【就绪态】的线程就有机会占用这个CPU去执行。所以yield的使用场景多在,当前线程在进行耗时性的操作时(如IO操作),并且因为它的优先级较高,导致一些优先级较低的线程被分配的时间片更少,这样优先级低的线程就要等待更长时间才能完成操作,那么这时适当地调用几次yield方法让出CPU,让优先级低的线程多得到执行,这样才能高效的实现程序执行和响应。

join()方法

join()方法是指等待调用join()方法的线程执行结束,程序才会继续执行下去,这个方法适用于:一个执行程序必须等待另一个线程的执行结果才能够继续运行的情况。

官方翻译:等待线程死亡,调用此方法的行为与调用完全相同。

d88a859960b5e6d716a258c257fc2c00.png

然后看一看join的具体实现,通过判断线程是否存活,一直调用wait()。

public final synchronized void join(long millis)

throws InterruptedException {

long base = System.currentTimeMillis();

long now = 0;

if (millis < 0) {

throw new IllegalArgumentException("timeout value is negative");

}

if (millis == 0) {

while (isAlive()) {

wait(0);

}

} else {

while (isAlive()) {

long delay = millis - now;

if (delay <= 0) {

break;

}

wait(delay);

now = System.currentTimeMillis() - base;

}

}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值