程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至CPU,数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。
进程就是用来加载指令、管理内存、管理IO的,当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程。
进程就可以视为程序的一个实例。大部分程序可以同时运行多个实例进程
一个进程之内可以分为一到多个线程。
一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给CPU执行
Java中,线程作为最小调度单位,进程作为资源分配的最小单位。在 windows 中进程是不活动的,只是作为线程的容器
单核cpu下,线程实际还是串行执行的。
操作系统中有一个组件叫做任务调度器,将cpu的时间片(windows 下时间片最小约为15毫秒)分给不同的线程使用,只是由于cpu在线程间(时间片很短)的切换非常快,人类感觉是同时运行的。
总结为一句话就是:微观串行,宏观并行
线程轮流使用CPU的做法就是并发
在多核cpu下每个核都可以调度运行线程,这时候线程可以是并行的
需要等待结果返回再去执行下一个“事件”就是同步
同步在多线程的可以指的是多个线程步调一致
遇到即时性一定要有返回结果的业务时使用
无需等待返回结果,直接进行下一个“事件”就是异步
多线程能够让方法执行变为异步的
例如遇到一个业务会占用很长的时间时我们可以使用异步避免主线程被堵塞
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
//创建线程
final Thread thread = new Thread(){
@Override
public void run() {
System.out.println("我是新线程");
System.out.println(Thread.currentThread().getName());
}
};
System.out.println("我是主线程");
//启动线程
thread.start();
}
public static void main(String[] args) {
System.out.println("我是主线程");
System.out.println(Thread.currentThread().getName());
new Thread(()->{
System.out.println("我是新线程");
System.out.println(Thread.currentThread().getName());
}).start();
}
创建TmpThread类实现Runnable接口,重写run方法
public class TmpThread implements Runnable {
@Override
public void run() {
System.out.println("我是新线程");
}
}
在new Thread
的时候传入TmpThread的实例,调用start方法开启
public static void main(String[] args) {
System.out.println("我是主线程");
System.out.println(Thread.currentThread().getName());
final TmpThread tmpThread = new TmpThread();
final Thread thread = new Thread(tmpThread);
System.out.println(thread.getName());
thread.start();
}
由于Runnable是函数式接口所以我们可以直接这样写
public static void main(String[] args) {
System.out.println("我是主线程");
System.out.println(Thread.currentThread().getName());
Runnable r = ()->{
System.out.println("我是新线程");
};
final Thread thread = new Thread(r);
System.out.println(thread.getName());
thread.start();
}
FutureTask能够接收Callable类型的参数,用来处理有返回结果的情况
public static void main(String[] args) throws ExecutionException, InterruptedException {
final FutureTask<String> stringFutureTask = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
return "使用callable创建线程";
}
});
final Thread thread = new Thread(stringFutureTask);
thread.start();
//阻塞,直到结果返回
final String s = stringFutureTask.get();
System.out.println(s);
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
final FutureTask<String> stringFutureTask = new FutureTask<String>(()->{
return "使用callable创建线程";
});
final Thread thread = new Thread(stringFutureTask);
thread.start();
//阻塞,直到结果返回
final String s = stringFutureTask.get();
System.out.println(s);
}