CodeGym /课程 /Java 核心 /创建和启动新线程

创建和启动新线程

Java 核心
第 6 级 , 课程 2
可用

“你好,阿米戈!艾莉给你介绍了线程,我将告诉你如何使用线程。要创建新线程,你需要:”

1) 创建 Thread 对象

2) 将其传递给你要运行的方法

3) 在所创建的 Thread 对象上调用 start 方法。

请考虑以下示例:

代码 说明
class Printer implements Runnable
{
public void run()
{
System.out.println("I’m printer");
}
}
实现 Runnable 接口的类。
public static void main(String[] args)
{
Printer printer = new Printer();
Thread childThread = new Thread(printer);
childThread.start();
}
1 创建实现 run 方法的 Printer 类的实例。
2 创建新的 Thread 对象。我们将 printer 对象传递给构造方法,需要调用该对象的 run() 方法。
3 通过调用 start() 方法启动新线程。

小型 Java 程序通常包含一个称为“主线程”的线程。但是更多的时候程序会启动附加线程,这些线程称为“子线程”。主线程运行和结束 main 方法。Runnablerun 方法是子线程的类似方法。

“哦,很多线程意味着很多 main 方法。”

创建和启动新线程 - 1

为了告诉 Thread 对象应该启动哪个特定方法,我们需要以某种方式向它传递一个方法。在 Java 中,使用 Runnable 接口完成此操作。此接口包含一个抽象方法:void run()。Thread 类包含 Thread(Runnable Runnable) 构造方法。可以传入实现 Runnable 接口的任何对象。

你的类必须继承 Runnable 并重写其 run 方法。调用此方法将启动新线程。你可以在 run 方法中写入任何内容。

代码 说明
class Printer implements Runnable
{
private String name;
public Printer(String name)
{
this.name = name;
}
public void run()
{
System.out.println("I’m " + this.name);
}
}
实现 Runnable 接口的类。
public static void main(String[] args)
{
Printer printer1 = new Printer("Nick");
Thread thread1 = new Thread(printer1);
thread1.start();

Printer printer2 = new Printer("Jack");
Thread thread2 = new Thread(printer2);
thread2.start();
}
创建两个线程,每个线程将基于自己的 Printer 对象。
public static void main(String[] args)
{
Printer printer = new Printer("Natasha");

Thread thread1 = new Thread(printer);
thread1.start();

Thread thread2 = new Thread(printer);
thread2.start();

Thread thread3 = new Thread(printer);
thread3.start();
}
基于单个 Printer 对象创建三个线程。

而且,你可以将所有这些组合到一个类中。Thread 类继承 Runnable 接口因此你只需重写run 方法:

创建新线程的另一种方法
class Printer extends Thread
{
private String name;
public Printer(String name)
{
this.name = name;
}
public void run()
{
System.out.println("I’m " + this.name);
}
}
继承实现 Runnable 接口的 Thread 类,然后重写 run 方法。
public static void main(String[] args)
{
Printer printer = new Printer("Jack");
printer.start();

Printer printer2 = new Printer("Jack");
printer2.start();

}
创建两个线程,每个线程将基于自己的 Printer 对象。

“这是一种更简洁的解决方法。”

“是的,但它也有缺点:”

1) 你可能需要基于一个对象启动多个线程,例如在娜塔莎那个示例中。

2) 如果你从 Thread 类继承,则无法将另一个父类添加到你的类中。

3) 如果你的类有一个父类,则无法将 Thread 添加为第二个父类。

“换句话说,在调用 start 方法之后,每个线程都开始执行传递给构造方法的对象的 run 方法吗?”

“是的。如果没有任何内容传递给构造方法,则 Thread 只执行其内部的 run 方法。”

“但是我们为什么不以这种方式调用方法呢?”

代码
public static void main(String[] args)
{
 Printer printer1 = new Printer("Nick");
 printer1.run();
}

“当主线程到达 run 方法时,它的‘小型机器人’只是进入内部并执行其中的所有命令。只有在执行完这些命令后,它才会返回到 main 方法并继续执行其他命令。因此,将不会创建第二个‘小型机器人’。所有工作将按顺序执行,而不是并行(同时)执行。”

“我明白了。你可以调用 run 之外的其他方法吗?”

“不可以。所有这些都与 Runnable 接口绑定,该接口只‘知道’它的一种方法:run()。”

评论 (7)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
momo 级别 22,China,China
10 十月 2022
为什么没有看到枚举和注解相关的章节?
kqhasaki 级别 23,Daxi,Taiwan, Province of China
17 八月 2021
如果仅仅是调用run(),而不是start(),那么主线程仅仅是进入run()中的任务,而不是开启一个并发的子线程。
ZZZNET 级别 16,United States of America
18 九月 2021
是的,只是调用run(),没有开启并发的子线程。
null 级别 17,Chengdu
15 三月 2021
请问怎么理解,最后一个代码的对应解释呢? “当主线程到达 run 方法时,它的‘小型机器人’只是进入内部并执行其中的所有命令。只有在执行完这些命令后,它才会返回到 main 方法并继续执行其他命令。因此,将不会创建第二个‘小型机器人’。所有工作将按顺序执行,而不是并行(同时)执行。”
wangwangwang 级别 20,Xiaogan
5 四月 2021
同问
liudakang 级别 20,Dongguan
19 五月 2021
我的理解是这里并没有创建新的线程,或者说没有线程进行start,相当于直接调用了这个类里面的run函数而已
kyrie 级别 18,重庆
3 八月 2021
但是由于每秒发生数百次线程切换,因此在我们看来,所有线程都在同时运行。 上一章讲的 所以 意思是如果到达run方法了 就不会产生线程的切换 跟以前的顺序进行是一样的 就从上往下执行程序 其他的线程就必须等 run 方法执行完再执行 因为run方法被占住了。