线程的概念
程序: Program,是一个指令的集合
进程: Process,(正在执行中的程序)是一个静态的概念
- 进程是程序的一次静态执行过程,占用特定的地址空间
- 每个进程都是独立的,由3部分组成 cpu data code
- 缺点内存的浪费,cpu的负担
线程是进程中一个“单一的连续控制流程”(a single Thread,equential flow of control)/执行路径
- 线程又被称为轻量级进程(lightweight process)
- Threads run at the same time, independently of another
- 一个进程可拥有多个并行(concurrent)线程
- 一个进程中的线程共享相同的内存单元/内存地址空间->可以访问相同的变量和对象,而且它们从同一堆中分配对象->通信、数据交换、同步操作
- 对于线程间的通信时在同一地址空间上进行的,所以不需要额外的通信机制,这就是的通信更简便而且信息传递的速度也更快
线程的创建方法:
- 继承Thread类
class Test extends Thread{
@Override
public void run() {
for (int i = 1; i < 100; i++) {
if (i % 2 == 0)
System.out.println(i);
}
}
}
public class Main {
public static void main(String[] args) {
Test t= new Test();
t.start();
}
}
- 实现Runnable接口
class Test implements Runnable{
@Override
public void run() {
for (int i = 1; i < 100; i++) {
if (i % 2 == 0)
System.out.println(i);
}
}
}
public class Main {
public static void main(String[] args) {
Test test = new Test();
Thread t = new Thread(test);
t.start();
}
}
- 实现Callable接口 有返回值
public class CallableThreadTest {
static class CallableThread implements Callable{
@Override
public Object call(){
return "from callable";
}
}
public static void main(String[] args) {
FutureTask futureTask = new FutureTask(new CallableThread());
Thread thread = new Thread(futureTask,"callable-thread");
thread.start();
try {
System.out.println("from main");
Thread.sleep(1000);
System.out.println(futureTask.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
推荐使用接口
- Java是单继承,将继承关系留给最需要的类
- 使用
Runnable
接口之后不需要给共享变量田间static
关键字,每次创建一个对象,作为共享对象
线程的生命周期
- 新生状态:当创建好当前线程对象之后,没有启动之前(调用
start()
方法之前)Thread t = new Thread();
- 就绪状态:准备开始执行,并没有执行,并表示调用
start()
方法之后
当对应的线程创建完成且调用start方法之后,所有的线程会添加到一个就绪队列中,所有的线程会同时去抢占cpu资源
- 运行状态:当当前进程获取到cpu资源之后,就绪队列中的所有线程回去抢占cpu资源,谁先抢到谁执行,在执行的过程中就叫做运行状态
抢占到运行资源,执行代码逻辑开始
- 死亡状态:当运行中的线程正常执行完所有的代码逻辑或者因为异常情况导致程序结束叫做死亡状态
1、正常运行完成并结束
2、认为中断执行,比如调用stop方法
3、程序抛出未捕获的异常
- 阻塞状态:在程序运行过程中,发生某些异常情况,导致当前进程无法在顺利执行下去,此时会进入阻塞状态,进入阻塞状态的原因消除之后,所有的阻塞队列会再次进入就绪状态中,随即抢占cpu资源,等待执行
1、sleep方法
2、等待io资源