1、线程和进程的区别
进程:是指一个内存中运行的应用程序(已经在内存中运行的程序). 一个进程都有一个独立的内存空间,一个电脑(手机)可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;
线程:是进程中的一个执行单元(线程是依赖于进程的),负责当前进程中程序的执行,一个进程中至少有一个线程(单线程程序)。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
并发和并行
前提
多个任务
多个线程
是线程的特性
高性能、高可用、高并发(三高)
并行:指两个或多个事件在同一时刻发生(同时发生 同时处理 执行者不是一个)。
并发:指两个或多个事件在同一个时间段内发生(交替的发生 执行者是一个)。
电脑在执行任务的时候是采用并发还是并行?
使用的是并发, 因为电脑上只有一个CPU,但是电脑上好像却可以同时运行多个程序,同时开了多个线程,其实这是一种假象,因为CPU的计算速度极快,约每秒50亿次计算,而人能感觉到的时间流失是秒,所以电脑给我们一种感觉好像电脑上程序在同时执行.
计算机CPU都是-Java抢占式调度。 每一个线程都会执行到,但是不一定时按序执行,执行取决于线程优先级,CPU有自己算法。
2 线程创建三种基本方式
2.1 继承Thread类
1、Thread就是一个线程类,里面定义所有和线程相关的功能,只有是这个类才能开启线程,才能被CPU单独去执行.Java中线程执行的时候是采用的并发(因为是让CPU执行JAVA中线程里封装的任务). 学习的过程中不要纠结于多个线程执行的结果,因为是随机在执行,抢占式的在使用CPU资源(抢占式任务调度)。
2、java虚拟机采用抢占式调度模型,是指优先让可运行池中优先级高的线程占用CPU(不绝对),如果可运行池中的线程优先级相同,那么就随机选择一个线程,使其占用CPU。
3、实现步骤
1、定义一个类MyThread继承Thread类 在MyThread类中重写run()方法,添加自己的任务
2、创建MyThread类的对象
3、启动线程 .start()
注意事项:千万不要使用线程对象调用run方法,因为并没有开启线程
观察结果:验证是否是抢占式调度。
public class ThreadExample extends Thread{
//重写run
@Override
public void run() {
for (int i = 0; i < 200; i++){
System.out.println("extends Thread run = " + i);
}
}
}
public class App {
public static void main(String[] args) {
ThreadExample te1 = new ThreadExample();
ThreadExample te2 = new ThreadExample();
//te.run();//调用run方法就没有开启线程,仅仅是使用线程对象调用了方
法而已
te1.start();
te2.start();
//main线程
for (int i = 0; i < 100; i++){
System.out.println("main Thread = " + i);
}
}
}
2.2 实现Runnable接口
1、@FunctionalInterface
public interface Runnable {
public abstract void run();
}
//这是一个函数式接口,规定里面只有一个run方法那么只需要让一个类实现Runnable接口即可,并且也需要覆写run方法。
2、Thread的构造方法创建对象的时候传入了Runnable接口的对象 Runnable接口对象重写run方法相当于指定线程任务,创建线程的时候绑定了该线程对象要做的任务
Runnable的对象称之为:线程任务对象 不是线程对象必须要交给Thread线程对象通过Thread的构造方法, 就可以把任务对象Runnable,绑定到Thread对象中, 将来执行start方法,就会自动执行。
3、实现步骤
1.定义一个类MyRunnable实现Runnable接口
2.在MyRunnable类中重写run()方法
3.创建MyRunnable类的对象
4.创建Thread类的对象,把MyRunnable对象作为构造方法的参数(绑定任务