面试时 面试官最常问的问题 所以今天整体复习一下。
多线程
前言
并发和并行
并发:指两个或多个事件在同一时间段内发生 ( 交替执行 )
并行:指两个或多个事件在同一时刻发生(同时发生 同时执行)
线程和进程
进程:是指一个内存中运行的运用程序,每个进程都有独立的内存空间,一个运用程序可以同时运行多个进程(同时打开两个QQ),进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。
线程:线程是进程中的一个执行单元,负责当前进程中的程序的执行,一个进程至少有一个线程。一个进程中是可以有多个线程的。这个程序称之为多线程程序。(同时执行软件的不同功能 如:一个杀毒软件同时执行病毒查杀,清理垃圾,电脑加速)
一个程序运行只是有一个进程,一个进程有多个线程。(通常一个功能开辟一条路径去cpu执行。这个路径就是线程)
线程调度
分时调度:轮流使用cpu 平均使用时间
抢占式调度:线程优先级高先调度。 java使用的就是为抢占式调度
怎么创建执行一个多线程的程序?
一、
Thread类
1.创建一个Thread类的子类
2.在Thread类的子类中重写Thread类中的run方法,设置线程任务(开启线程后要做什么)
3.创建Thread类的子类的对象
4.调用Thread类中的方法start方法,开启新的线程,执行run方法
常用方法
start
run
sleep
计时60s
public class Sleep {
public static void main(String[] args) {
for (int i = 0; i < 60; i++) {
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
二、
实现Runnable接口
1.创建一个Runnable接口实现类
2.在实现类中重写Runnable接口的run方法,设置线程任务
3.创建一个Runnable接口的实现类对象
4.创建Thread类对象,构造方法中传递Runnable接口的实现类对象
5.调用Thread类中的start方法,开启新的线程执行run方法。
好处:
避免继承了单继承的局限性
增强了程序的扩展性,降低程序的耦合性。
线程安全问题
多线程访问共享的数据,在一个线程还没完成另外一个线程就进入cpu操作。就会产生线程安全问题
解决线程安全问题
1.同步代码块
格式:
synchromnized(同步锁对象 ){
可能出现线程安全的代码 (同步代码块、锁对象的代码)
}
理解:
当多个线程抢一个cpu的执行权时,其中有个线程抢到了cpu的执行权,执行run方法,遇见synchromnized代码块是否有锁对象,如果有,就会执行锁对象。
在第一个线程没执行完成时,又有一个线程抢到了cpu的执行权,执行run方法,遇见synchromnized代码块,但因为第一个线程没执行完成,发现没有锁对象(代码块)。然后这个线程会进入阻塞状态,会一直等到第一个线程执行完,把锁对象归还。然后第二个进程解除阻塞状态,然后执行锁对象…
简单的来说同步代码块:同步中的线程,没有执行完不会释放锁对象。同步外的没有锁对象就进不去同步。
2.同步方法
格式:
修饰符 synchronized 返回值类型 方法名(参数列表){
可能出现线程安全的代码 ( 同步代码块)
}
静态:同步方法所在类的字节码,类名.class
非静态:this
3.Lock锁
格式:
Lock 对象名 =new ReentrantLock();
对象名.lock();
可能出现线程安全的代码
对象名.unlock();