1. 线程概述
进程(Process)代表运行中的程序。一个运行中的java程序就是一个进程。从操作系统的角度来看,线程(Thread)是进程中可独立执行的子任务。一个进程可以包含多个线程,同一进程中的线程共享该进程所申请到的资源,如内存空间,文件句柄等。从jvm的角度来看,线程是进程中的一个组件(Compoent),它可以看作执行java代码的最小单位。java程序中的任何一段代码总是执行在一个确定的线程中。JVM启动时会创建一个main线程,来执行程序的入口main方法。
2.线程创建和执行
2.1 代码
package com.bdf.blog.thread;
/**
* @program: blog
* @description:
* @author: tianpeirong
* @create: 2019-03-14 09
**/
public class StartThread {
public static void main(String[] args) {
System.out.println("The Main method was executed by Thead: " + Thread.currentThread().getName());
new ThreadDemo1("hello java").start();
}
}
package com.bdf.blog.thread;
/**
* @program: blog
* @description:
* @author: tianpeirong
* @create: 2019-03-14 09
**/
public class ThreadDemo1 extends Thread {
private String msg;
public ThreadDemo1(String msg) {
this.msg = msg;
}
@Override
public void run() {
doSomething(msg);
}
private void doSomething(String msg) {
System.out.println("The doSomething method was executed by Thread" + Thread.currentThread().getName());
System.out.println("The doSomething with " + msg);
}
}
运行结果
The Main method was executed by Thead: main
The doSomething method was executed by ThreadThread-0
The doSomething with hello java
2.2 解析
在java语文中,线程就是java.lang.Thread类的实例。JVM会为一个Thread实例分配两个调用栈(call stack)所需的内存空间。这两个调用栈一个用于跟踪java代码之间的调用关系,另一个用于跟踪java代码对本地代码(即Native代码,通常为C)的调用关系。启动一个java程序只需要调用其实例的start()方法。
3线程的状态切换
java语言中,一个线程从其创建、启动到其运行结束的整个生命周期可能经历若干个状态,如图
线程的状态可以能过相应Thread实例的getState()方法获取。
将上面的main方法修改
package com.bdf.blog.thread;
/**
* @program: blog
* @description:
* @author: tianpeirong
* @create: 2019-03-14 09
**/
public class StartThread {
public static void main(String[] args) throws InterruptedException {
System.out.println("The Main method was executed by Thead: " + Thread.currentThread().getName());
ThreadDemo1 threadDemo1 = new ThreadDemo1("hello java");
System.out.println(threadDemo1.getState());
threadDemo1.start();
Thread.sleep(1000);
System.out.println(threadDemo1.getState());
}
}
代码结果
The Main method was executed by Thead: main
NEW
The doSomething method was executed by ThreadThread-0
The doSomething with hello java
TERMINATED
Thread.state所定义的线程状态分类以下几种:
- NEW: 一个刚创建而未启动的线程处于该状态。由于一个线程实例只能够被启动一次,因此一个线程只可能有一次处于该状态。
- RUNNABLE: 该状态可以看成一个复合状态。它包括两个子状态:READY和RUNNING。前者表示处于该状态的线程可以被JVM的线程调度器(Scheduler)进行调度而使之处于Running状态。后者表示该状态的线程正在运行,即相应线程对象的run方法中的代码所对应的指令正在由CPU运行。当Thread实例的yield方法被调用时或者由于线程调度器的原因,相应线程的状态会由Running转换为READY.
- BLOCKED: 一个线程发起一个阻塞式I/O(BLOCKING I/O)操作后,或者试图获取有一个由其他线程持有的锁时,相应的线程就会处于该状态。处于该状态的线程不会占用CPU资源。当相应的I/O操作结束后,或者相应的锁被其他线程释放后,该线程的状态又可以转成RUNNABLE.
- WAITING: 一个线程执行了某些方法之后就会进入一种无限等待的状态。。这些方法包括:Object.wait()、Thread.join()和LockSupport.park()。能够使相应线程从WAITING转换到RUNNABLE的相应方法包括:Object.notify()、Object.notifyAll()和LockSupport.unpark(thread)。
- TIMED_WAITING:该状态和WAITING类似,差别在于处于该状态的线程并非无限等待其他线程执行特定操作,而是处于带有时间限制的等待状态。当时间结束,该线程的状态自动转换为RUNNABLE。
- TERMINATED:已经执行结束的线程处于该状态。由于一个线程实例只能够被启动一次,因此一个线程也只可能有一次处于该状态。Thread实例的run方法正常返回或者由于抛出异常而提前终止都会导致相应线程处于该状态。