并发/线程
多任务,这是操作系统的一种能力,看起来可以在同一时刻运行多个程序。
并发执行的进程数目并不受限于CPU数目。
操作系统会为每个进程分配CPU时间片,给人并行处理的感觉。
多线程程序在更低一层扩展了多任务的概念:单个程序看起来在同时完成多个任务。
每个任务在一个线程中执行,线程是控制线程的简称。
如果一个程序可以同时运行多个线程,则称这个程序是多线程的。
多进程与多线程的本质区别在于每个进程都有自己的一整套变量,而线程则共享数据。
虽然这有风险,但是共享变量使线程之间的通信比进程之间的通信更有效、更容易。
此外,在有些操作系统中,与进程相比,线程更轻量级,创建、撤销一个线程比启动新进程的开销要小得多。
通过Runnable接口定义线程
public interface Runnable{ // Runnable接口很简单,只有一个方法
void run(); // 必须覆盖这个方法,提供你希望执行的任务指令
}
// 由于Runnable是一个函数式接口,可以用一个lambda表达式创建一个实例
Runnable r = () -> {...};
// 从这个Runnable构造一个Thread对象
var t = new Thread(r);
// 启动线程
t.start();
还可以通过建立Thread类的一个子类来定义线程
class MyThread extends Thread{
public void run(){
...
}
}
然后构造这个子类的一个对象,并调用它的start方法。
不过现在不推荐这种方法。
应该把要并行运行的任务与运行机制解耦。
如果有多个任务,为每个任务分别创建一个单独的线程开销会太大。
所以,可以使用一个线程池。
不要调用Thread类或者Runnable对象的run方法。
直接调用run方法只会在同一个线程中执行这个任务,而没有启动新的线程。
实际上,应该调用Thread.start方法,这会创建一个执行run方法的新线程。