一、进程和线程的概述
1、什么是进程?
正在运行的程序,是系统进行资源分配和和调用的独立单位。每一个进程都有它自己的内存空间和系统资源。
2、多进程有什么意义?
单进程计算机只能做一件事情,而我们现在的计算机都可以做多件事情
例如:一边玩游戏,一边听音乐
现在的计算机都是支持多进程的,就可以在一个时间段内执行多个任务,提高CPU的使用率;
3、什么是线程?
在一个进程内可以执行多个任务,每一个任务可以看成一个线程
线程是程序的执行单元,执行路径,是程序使用CPU的基本单位;
单线程:程序一条执行路径
多线程:程序有多条执行路径
4、多线程有什么意义?
多线程的存在不是提高执行速度,而是为了提高应用程序的使用率
程序的执行其实都是在抢CPU的资源,线程越多,该进程抢到资源几率更高
5、并发和并行
并行是指在同一个时间内,并发是指在同一个时间点
6、java程序运行原理
jvm启动相当于启动了一个进程,接着该进程创建一个主线程调用main方法
jvm启动是多线程的,原因是垃圾回收线程也要启动。
7、如何实现多线程程序?
1、继承Thread类并且重写run方法,创建对象,启动线程,只有run方法中的代码需要被线程执行
调用run方法与普通方法调用一样。
run:封装被线程执行的代码 start:先启动线程,再由jvm调用run方法
2、实现Runable接口
自定义类实现Runable接口,重写run方法,创建对象,创建Thread对象 ,启动线程
方式二解决了单继承的局限性
适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码没数据有效分离,较好体现了 面向对象的思想。
---------public static Thread currentThread();获得当前线程对象
8、线程调度
1、分时调度:所有线程轮流使用CPU使用权
2、抢占式调度:优先让优先级高的线程使用CPU(java使用)
如何设置和获取线程优先级?
public final int getPriority():返回线程优先级,默认是5
public final void setPriority(int newPriority):设置优先级 1-10
9、线程休眠
public static void sleep(毫秒)
10、线程加入
public final void join();等该线程执行完毕后才执行后续
11、线程礼让
public static void yeild();暂停当前线程,让其他线程先执行,让多线程执行更加和谐
12、守护线程
public static void setDaemon(boolean on) 将该线程标记为守护线程
当只有守护线程运行时,java虚拟机退出,该方法必须在启动线程前调用
13、中断线程
public void interrupt()把线程状态终止并抛出异常
14、线程的生命周期
新建:创建线程对象
就绪:有执行资格,没有执行权
运行:有执行资格,有执行权
阻塞:由于一些操作让线程阻塞,没有资格和执行权,另外一些操作可以激活使其有执行资格
死亡:线程对象变成垃圾,等待被回收
15、线程安全问题
哪些原因会导致多线程问题?
A、是否是多线程环境
B、是否有共享数据
C、是否有多条语句操作共享数据
解决办法,同步代码块
synchronized(对象){需要同步的代码}能够解决问题的根本原因在对象上,该对象如同锁的功能,要求多线程同一把锁。
同步:前提:多线程 多个线程使用同一个锁对象 好处:解决多线程安全问题 弊端:每次判断锁,耗费资源
同步方法的格式和锁对象问题:同步方法的锁对象是什么?this; 静态方法锁对象是当前类的class对象
二、死锁问题
同步弊端:效率低,如果出现了同步嵌套,容易产生死锁问题
四个必要条件 (1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系
ab两个锁对象,两个线程,线程一flag=true,执行a锁语句再执行b锁,线程二flag==false,执行b锁语句再执行a锁。
三、生产着消费者模型(等待唤醒机制)
Object中的方法:wait,notify,notifyAll,为什么这些方法不定义在Thread类中?
因为这些方法调用通过锁对象调用,锁对象是任意类型的。
- wait 表示持有对象锁的线程A准备释放对象锁权限,释放cpu资源并进入等待。
- notify 表示持有对象锁的线程A准备释放对象锁权限,通知jvm唤醒某个竞争该对象锁的线程X。线程A synchronized 代码作用域结束后,线程X直接获得对象锁权限,其他竞争线程继续等待(即使线程X同步完毕,释放对象锁,其他竞争线程仍然等待,直至有新的notify ,notifyAll被调用)。
- notifyAll 表示持有对象锁的线程A准备释放对象锁权限,通知jvm唤醒所有竞争该对象锁的线程,线程A synchronized 代码作用域结束后,jvm通过算法将对象锁权限指派给某个线程X,所有被唤醒的线程不再等待。线程X synchronized 代码作用域结束后,之前所有被唤醒的线程都有可能获得该对象锁权限,这个由JVM算法决定
四、线程组
把多个线程组合到一起
它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。
ThreadGroup tg = new ThreadGroup(“name”)
Thread th = new Thread(tg,实现Runable接口的类,线程名);
通过线程组可以设置优先级、后台等。
五、线程池
线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用
A:创建一个线程池对象 public static ExecutorService newFixedThreadPool(int nThreads)
B:这种线程池的线程可以执行:
Runnable对象或者Callable对象
做一个类实现Runnable接口
C:调用如下方法
Future<?>submit (Runnable task )
<T> Future <T>submit (Callable<T> task)