为什么要使用多线程?
如果想要学好多线程,首先必须了解多线程的由来和作用。
当单线程执行任务时,假设执行单次任务消耗的时长为1秒,执行1000次任务,消耗的时间为1000秒,折合分钟大约为17分钟。
当多线程执行任务时,假设执行单次任务消耗的时长为1秒,执行1000次任务,分为10个线程同时执行,分配给每个线程的时间为100次,消耗的时间为100秒,折合分钟为1分40秒。
简而言之,多线程就是利用并行的思想,缩短计算处理时长。
Runnable创建方式
一说到线程,大家最容易想到的就是Runnable,那如何创建一个Runnable呢?
方式一:通过实例化一个Runnable对象,交给Thread类来执行,代码如下:
public class RunnableTest01 {
public static class CustomRunnable implements Runnable {
public void run() {
System.out.println("异步执行操作,当前线程:" + Thread.currentThread().getName());
}
}
public static void main(String[] args) {
new Thread(new CustomRunnable()).start();
System.out.println("主线程:" + Thread.currentThread().getName());
}
}
结果打印:
主线程:main
异步执行操作,当前线程:Thread-0
方式二:通过继承Thread,代码如下
public class RunnableTest02 {
public static class CustomThread extends Thread{
@Override
public void run() {
System.out.println("异步执行操作,当前线程:" + Thread.currentThread().getName());
}
}
public static void main(String[] args) {
new CustomThread().start();
System.out.println("主线程:" + Thread.currentThread().getName());
}
}
结果打印:
主线程:main
异步执行操作,当前线程:Thread-0
为什么要用Thread类的start方法,而不是run方法?如果使用run方法会怎样?
如果大家自己在编写多线程代码时,肯定会发现Thread类提供了run方法,假设,我们不适用start方法,而是调用run方法,结果会怎么样?首先看结果打印:
异步执行操作,当前线程:main
主线程:main
那么实际执行run方法代码块的是主线程,而不是新开启的子线程。
那么start方法到底做了什么事情,我们来看源代码,如下所示:
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
// 最终调用的是start0方法,而start0方法标注了native,是java本地方法,底层调用C、C++实现
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}
private native void start0();
有兴趣的可以深入研究下start0背后Java如何处理。
总而言之,如果直接调用run方法,程序会在调用者线程执行,如果调用start,java会通过系统级调用执行程序。