多线程
进程与线程
-
进程:正在操作系统中运行的一个程序
-
线程:线程是进程的一个执行单元
进程是线程的容器,一个进程至少有一个线程,一个进程中也可以有多个线程,每个线程都有各自的线程栈,都有自己的寄存器环境,自己的线程本地存储
主线程与子线程
主线程:jvm启动的时候会创建一个主线程,负责执行main方法,主线程就是运行main方法的线程
子线程:比如在A线程中创建一个B线程,那么B线程就是A线程的子线程
创建线程的两种方式
1.继承Thread类创建线程
public class MyThread extends Thread{
//继承Thread类
//重写Thread中的run
@Override
public void run() {
System.out.println("这是子线程打印的内容");
}
}
public class TestThread {
public static void main(String[] args) {
System.out.println("jvm启动main线程,执行main方法");
//创建子线程对象
MyThread myThread = new MyThread();
//启动线程
myThread.start();
//start()方法调用结束并不是意味着立即执行 具体什么时候运行,由线程调度器决定
System.out.println("main线程结束后的代码");
}
}
2.实现Runnable接口
public class MyRunnable implements Runnable{
//实现Runnable接口
@Override
public void run() {
}
}
public class RunnableTest {
public static void main(String[] args) {
//创建Runnable接口的对象
MyRunnable myRunnable = new MyRunnable();
//创建线程对象
Thread thread = new Thread();
//开启线程
thread.start();
}
}
线程的生命周期
新建状态: new Thread之后就进入了新建状态
就绪状态:调用start方法之后线程就会处于就绪状态,虚拟机会为当前程序创建线程栈和程序计数器
运行状态:当处于就绪状态的线程获得CPU,它就会执行run()方法(所以run()方法是由线程获得CPU以后自动执行
阻塞状态 :等待阻塞 同步阻塞 其他阻塞
当如下情况发生时,线程会进入阻塞状态:
1、线程调用sleep()方法主动放弃占用的处理器资源;
2、线程调用了一个阻塞式IO方法,在该方法返回以前,该线程被阻塞;
3、线程试图获得一个同步监视器,但该监视器被其他线程持有;
4、线程在等待某个通知;
5、线程调用suspend()方法将该线程挂起。但这个方法容易导致死锁,不建议使用;
如何让线程重新进入就绪状态,有如下几种情况:
1、调用sleep()方法的线程经过了指定时间;
2、线程调用的阻塞式IO方法已经返回;
3、线程成功地获得了试图取得的同步监视器;
4、线程在等待通知时,其他线程发出了一个通知;
5、处于挂起状态的线程被调用了resume()恢复方法;
死亡状态:
线程会在如下几种情况结束(结束后就处于死亡状态)
1、run()/call()方法执行完成,线程正常结束;
2、线程抛出一个未捕获的Exception或Error;
3、直接调用线程的stop()方法结束该线程——该方法容易导致死锁,通常不建议使用。