以下介绍几种线程常见的创建方法:
CodeBlock-1:
/**
* 线程的创建方式1:继承Thread类
*/
public class Demo_extends extends Thread {
@Override
public void run() {
while (!interrupted()) {
System.out.println(getName() + "线程开始执行");
}
}
public Demo_extends(String name) {
super(name);
}
public static void main(String[] args) {
Demo_extends d1 = new Demo_extends("first-thread");
Demo_extends d2 = new Demo_extends("second-thread");
// d1.setDaemon(true);
// d2.setDaemon(true);
d1.start();
d2.start();
d1.interrupt();
d2.interrupt();
}
}
CodeBlock-2:
/**
* 实现Runnable接口实现线程创建
* 但是其不是作为一个线程类去创建线程对象
* * 而是作为一个线程任务而存在(即线程所要执行的功能)
*/
public class Demo_implement implements Runnable {
@Override
public void run() {
while(true){
System.out.println("Thread"+" is running.");
}
}
public static void main(String... args) {
Thread thread = new Thread (new Demo_implement());
thread.start();
System.out.println( thread.getId());
try {
thread.wait(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
CodeBlock-3:
/**
* 实现Runnable接口实现线程创建
* 但是其不是作为一个线程类去创建线程对象
* * 而是作为一个线程任务而存在(即线程所要执行的功能)
*/
public class Demo_implement implements Runnable {
@Override
public void run() {
while(true){
System.out.println("Thread"+" is running.");
}
}
public static void main(String... args) {
Thread thread = new Thread (new Demo_implement());
thread.start();
System.out.println( thread.getId());
try {
thread.wait(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
CodeBlock-4:
public class Demo_anonymous {
public static void main(String[] args) {
// new Thread(){
// @Override
// public void run() {
// System.out.println("Thread start...");
// };
// }.start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread start...");
}
}).start();
}
}
父线程的概念是我在翻阅Java-jdk1.8代码的时候看到的,父线程概念第一次是在Thread类的Init方法中提到的,其中g是ThreadGroup类定义的对象。Thread规定,如果Thread构造器在调用的时候没有输入线程组,那么就默认父线程的组为当前线程的组。
CodeBlock-5:
Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
/* Determine if it's an applet or not */
/* If there is a security manager, ask the security manager
what to do. */
if (security != null) {
g = security.getThreadGroup();
}
/* If the security doesn't have a strong opinion of the matter
use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}
父线程是“创造子线程的线程”,也就是子线程构造方法所被调用的线程,也即当前线程:Thread parent = currentThread();
因为此时子线程在创建中,且未启动,父线程就是当前线程。
而将父线程的组别复制给子线程的组,是通过g = parent.getThreadGroup();
语句实现的。
父线程的提出是沿用于继承中的父子关系中,“创建子类对象,首先要执行父类静态代码块,构造代码块再进行子类的构造”这种先后顺序关系。父线程强调的是,父线程的创建先于子线程,父线程中创造并初始化子线程,没有父线程就没有子线程。但是父线程的结束对子线程没有影响,如以下代码块-6;
CodeBlock-6:
public class CreateThread4 {
public static void main(String[] args) {
final Thread thread1 = new Thread(()-> System.out.println(Thread.currentThread().getName()+" is finished"));
thread1.start();
System.out.println("thread1线程的组名:"+thread1.getThreadGroup());
System.out.println("main线程的组名:"+Thread.currentThread().getThreadGroup());
System.out.println(Thread.currentThread().getName()+" is finished");
}
}
控制台输出:
thread1线程的组名:java.lang.ThreadGroup[name=main,maxpri=10]
main线程的组名:java.lang.ThreadGroup[name=main,maxpri=10]
main is finished
Thread-0 is finished
可见子线程和父线程执行完毕的顺序实际并没有要求,父线程可以先执行完毕。