Java并发编程艺术 - 多线程构造和启动

构造线程

在运行线程之前首先要构造一个线程对象,线程对象在构造的时候需要提供线程所需要的属性,如线程所属的线程组、线程优先级、是否是Daemon线程等信息。

线程启动

线程对象在初始化完成之后,调用start()方法就可以启动这个线程。

线程start()方法的含当前线程(即parent线程)同步告知Java虚拟机,只要线程规划器空闲,应立即启动调用()方法的线程。

注意 启动一个线程前,最好为这个线程设置线程名称,因为这样在使用jstack分析或者进行问题排查时,就会给开发人员提供一些提示,自定义的线程最好能够起个名字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class ThreadTest {

Runnable target;
char[] name;
boolean daemon;
int priority;

public Thread init(Runnable target, String name) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
// 当前线程就是该线程的父线程
Thread parent = currentThread();
// 将daemon、priority属性设置为父线程的对应属性
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
this.name = name.toCharArray();
this.target = target;

//构造线程组,便于统一管控
ThreadGroup g = new ThreadGroup(name + "Group");
g.setDaemon(daemon);
g.setMaxPriority(priority);

//构造线程
Thread thread = new Thread(g, target, name);

return thread;
}

public void run(Thread thread) {
//处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行相应线程的run()方法
thread.start();

//run()就和普通的成员方法一样,可以被重复调用
//thread.run();
}


public static void main(String[] args) {
//执行方法
Runnable runnable = () -> {
System.out.println("Test");
};

ThreadTest threadTest = new ThreadTest();

while (true) {
threadTest.run(threadTest.init(runnable, "Test"));
}
}
}

实现并启动线程有两种方法

  1. 写一个类继承自Thread类,重写run方法。用start方法启动线程
  2. 写一个类实现Runnable接口,实现run方法。用new Thread(Runnable target).start()方法来启动

start()和run()

  1. start启动线程,无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。

    然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。

  2. run方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码。
------ 本文结束------

本文标题:Java并发编程艺术 - 多线程构造和启动

文章作者:Perkins

发布时间:2019年08月29日

原始链接:https://perkins4j2.github.io/posts/58008/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。