前言
大家好,一直以来我都本着用最通俗的话理解核心的知识点, 我认为所有的难点都离不开 「基础知识」 的铺垫。目前正在出一个Java多线程专题长期系列教程,从入门到进阶, 篇幅会较多, 喜欢的话,给个关注❤️ ~
适合人群
- 有一定的Java基础
- 想学习或了解多线程开发
- 想提高自己的同学
- 「大佬可以绕过 ~」
背景
之前给大家讲了一些框架的使用,这些都属于业务层面的东西,你需要熟练掌握它并在项目中会运用它即可,但这些对自身技术的积累是远远不够的,如果你想要提高自己,对于语言本身你需要花更多的时间去挖掘而不是局限于框架的使用,所以之前为什么跟大家一直强调基础的重要性,框架可以千变万化,层出不穷,但是基础它是不变的,不管是学java还是前端或者是其它语言, 这一点大家还是需要认清的。
接下来的几期会专门讲多线程这一块,篇幅会较多,耐心看完你一定会有收获~
情景回顾
上期带大家学习了什么是进程什么是线程,理解了它们的基本概念,本期正式学习Java多线程开发,本节主要带大家入门,认识一些常用的类和接口,我们一起来看一下吧~
Thread 类
在JDK中,提供了一个Thread类,我们只需要继承这个类,就可以实现多线程:
public class ThreadTest {
public static class MyThread extends Thread {
public void run() {
System.out.println("hello 2");
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
// 启用线程 (不调用是没法启动的)
myThread.start();
System.out.println("hello 1");
}
}
最后结果输出:
hello 1
hello 2
我们可以发现hello2明明在上面运行,为啥最后输出,因为它启动的是独立的线程执行,所以不会造成阻塞,所以调用start的时候,后续代码会继续执行,无需等待hello2的结果。
那么我可以调用多次start吗❓这样是不是可以多开几个线程,我们试试看:
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
System.out.println("hello 1");
myThread.start();
}
运行一下:
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:710)
at com.thread.base.ThreadTest.main(ThreadTest.java:23)
好家伙,直接报错,那么原因是什么呢?
为什么start()不可以调用多次
首先我们要明白,Java中,线程是不允许启动两次的,启动第二次就会抛出IllegalThreadStateException的异常。那么这个异常为啥抛呢?我们只要找到start方法中抛这个异常的地方不就好了,下面我们看下源码:
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
....
}
好家伙,点进去就找到了,说明,每次调用的时候,首先都会判断 threadStatus 是否为0。这个0代表的是线程NEW状态,也就是说第二次调用线程可能会处于非NEW状态。其实这里涉及到线程生命周期的概念了,先不给大家讲解, 后边给大家讲,这一节,我们先入门。
Runnable 接口
我们还可以通过实现Runnable接口,来开启多线程。我们来看一下:
public class RunnableTest {
public static class MyThread implements Runnable {
public void run() {
System.out.println("hello 2");
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
System.out.println("hello 1");
}
}
看下输出:
hello 1
hello 2
new Thread,其实还有通过java8的特性表达式,还可以这样使用:
new Thread(() -> {
System.out.println("hello3");
}).start();
这样也可以开启一个多线程。
结束语
本期到这里就结束了, 总结一下,本节主要讲了Thread类和Runnable接口,以及带大家实际操作了一下,大家可以自己多试试。