如何创建和启动线程

本文详细介绍了Java中创建线程的两种方式:继承Thread类和实现Runnable接口,并分析了start()方法的重要性,强调了直接调用run()与调用start()的区别,最后总结了正确启动线程的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Runnable接口

我们看Thread类的定义知道,Thread类实现了Runnable接口

Runnable接口的定义如下:

它只有一个抽象方法run。说明需要其实现类重写这个run方法,而run()之间的内容,就是我们期望这个线程该干什么。
同时Runnable接口还被@FunctionalInterface注解标注,说明它是一个函数式接口。这意味着,可以使用Lambda表达式来创建Runnable接口的实例。

线程创建

在Java中,创建一个线程的方式,有且仅有一种方式:
创建一个Thread类实例,并调用它的start方法。

Thread的构造函数

Thread的构造函数有8个,主要就是给四个参数赋不同的值,这四个参数分别是:
ThreadGroup g (线程组)
Runnable target(Runnable对象)
String name(线程的名字)
long stackSize(为线程分配的栈的大小,若为0则表示忽略这个参数)
我们最常用的就是 ②③

对于线程的名字,其默认值为:“Thread- ” +nextThreadNum()。
nextThreadNum():

就是一个简单的递增计数器,如果我们创建线程时没有指定线程名,那线程名就会是:Thread-0,Thread-1,Thread-2....

至此,虽然Thread的构造函数很多,但对我们来说,真正的参数只有一个:

Runnable target(Runnable对象)

前面我们说过Thread类实现了Runnable接口,所以它必定会重写run(),我们来看一下,Thread类中的run():

可以看到,其实在Thread类的run(),还是调用了Runnable的run(),即如果我们在创建线程时,没有传入target,则这个run方法就什么也不会做。

启动线程

在创建完线程后,我们就要启动线程,启动一个线程必须调用线程的start()

start()方法本质调用了start0(),start0()方法是一个本地方法,这个方法使得线程开始执行,并由JVM来执行这个线程的run方法,结果就是有两个线程在并发执行,一个是当前线程,也就是调用了Thread类中的start方法的线程,另一个线程就是当前你Thread对象代表的线程, 它执行了run()。

也就是说,这个Thread类实例代表的线程最终会执行它的run方法。

这个时候就出现了问题:

当我们调用start()后,到最后还是执行了run(),那为什么我们一开始不直接调用Thread类中的run或target对象的run()呢?

这样做是为了使用我们的多线程。Thread类从定义上看就是我们的一个普通的类,是什么东西让一个普通的类变成能创建多线程的类呢?
是native方法!

如果我们直接调用Thread类中的run()或target中的run(),仅仅是一个普通的调用,但是如果我们调用了start(),start方法内部会调用一个本地方法start0(),它将导致一个新的线程被创建出来,而我们的Thread实例,就代表了这个新创建出来的线程,并由这个新创建出来的线程来执行Thread实例的run()。

实战

<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值