我正在参与掘金创作者训练营第6期,点击了解活动详情
前言
上篇我们聊到过,并发编程相关知识是面试中非常高频的考察点,其中线程肯定是重中之重。本篇就来认识一下项目业务中很常见的线程,可以说掌握了它,并发编程这块也就那么回事。
文章概览
1. 线程的状态
Java开发中,线程的6种状态:
- 初始(NEW):新创建线程对象,还没有调用
start()方法 - 运行(RUNNABLE):Java 线程中将就绪(ready)和运行中(running)状态统称为“运行”。线程对象创建后,调用该对象的
start()此时线程位于可运行线程池中,等待被线程调度选中,获取 CPU 的使用权,此时处于就绪状态(ready)。就绪状态线程在获得 CPU 时间片后变为运行中状态(running)。 - 阻塞(BLOCKED):锁对象阻塞线程
- 等待(WAITING):该状态线程需要等待其他线程做出一些特定动作(通知或中断)
- 超时等待(TIMED_WAITING):不同于WAITING,可以在指定的时间后自行返回
- 终止(TERMINATED):线程已经执行完毕
2. 线程启动
常用的创建和启动线程方式:
- className extends Thread,重写
run()方法,调用start()运行 - className implements Runnable,重写
run()方法,由Thread运行
/* 继承 Thread,重写 run() 方法 */
private static class UseThread extends Thread {
@Override
public void run() {
System.out.println( "extends Thread" );
}
}
/* 实现 Runnable 接口 */
private static class UseRunnable implements Runnable {
@Override
public void run() {
System.out.println( "implements Runnable" );
}
}
// 创建和启动线程
/* 使用 Thread 创建线程 */
UseThread useThread = new UseThread();
useThread.start(); //启动线程
/* 使用 Runnable 创建线程 */
UseRunnable useRunnable = new UseRunnable();
new Thread( useRunnable ).start(); // 启动
}
继承 Thread 的方式和实现 Runnable 的方式,执行完成后无法返回结果
3. run()和start()
new Thread() 只是 new 出一个 Thread 对象,调用 start() 方法后,才真正启动线程。
run() 只是一个成员方法,和普通方法并无差异,可重复执行。
示例如下:
public static class StartAndRunDemo extends Thread {
@Override
public void run() {// 重写run
System.out.println("run: This is " + Thread.currentThread().getName());
}
public void runMethod() { //定义成员方法 runMethod
System.out.println("runMethod: This is " + Thread.currentThread().getName());
}
}
// 调用线程
StartAndRunDemo startAndRun = new StartAndRunDemo();
startAndRun.setName("ThreadRun"); // 设置线程名
startAndRun.start(); // 真正启动名为 ThreadRun 的线程
startAndRun.run(); // 调用一个普通成员方法,和 runMethod() 没有区别
startAndRun.runMethod();
}
运行结果:
run: This is main
runMethod: This is main
run: This is ThreadRun
4. 线程终止
线程的终止,要么run() 执行完成,要么抛出异常导致线程结束,当然啦,也可以手动中止线程,线程 API 提供 stop()、resume()、suspend() 方法,但都已被标记为 @deprecated,已过时了,不建议使用,因为在调用这几个后,线程不会释放已占有的资源,容易导致死锁问题。
安全中止线程,可以调用 interrupt() 方法,它是一种协作的,只是发送一个中断信号,不代表线程会立即停止,会先通过 isInterrupted() 方法判断是否中止线程。
在掘金(JUEJIN) 一起分享知识, Keep Learning!