1、进程与线程
进程:指具有独立功能的程序在一个数据集合上运行的过程,是系统进行资源分配和调度的一个独立单位。
线程:指进程中的一个执行单元,一条执行路径。可以有多条线程执行,当有多条线程执行时,cpu会在其之间相互切换。
进程可以有多个线程,但至少有一个线程,每个进程都有自己独立的一块内存。线程共享进程的堆内存和方法区资源,但每个线程有自己的程序计数器、虚拟机栈和本地方法栈
2、同步与异步
同步:排队执行,一个接一个,有序执行,效率低但是安全
异步:同时执行,一起执行,效率高但不安全,极易造成数据丢失等情况
3、线程创建方式
1)继承Thread 类:重写run()方法,run()方法就是一条新的执行路径;注意:该方式下启动线程方式为:start()方法启动
2)实现Runnable 接口:需要将Thread类对象当作参数传入,同样以start()方法启动
用实现runnable接口的优势或好处:
a:通过创建任务,然后分配的方式来实现多线程在实际应用开发中更加合适。
b:可以避免单继承所带来的局限性。
c:任务与线程是分离的。
d:后续在使用线程时,线程池只接受runnable类型任务,不接受直接继承thread
3)带返回值的Callable 接口:重写call()方法
4、线程的一些方法
1)设置或获取线程的名称,getName()、currentThread()等等
2)线程休眠以及唤醒:sleep()使线程睡眠,notify()随机唤醒一个睡眠线程,notifyAll()唤醒所有正在睡眠的线程
3)线程中断:由该线程本身决定,通过interruput()打上中断标记,然后在异常中return。
……
5、线程的六种状态
创建、阻塞、运行、睡眠、等待、终止,不管线程此时处于何种状态,最后线程都会终止。注意:死锁问题,a和b同时拿着自己的锁,使用cpu资源,此时a和b又想拿到互相的锁且还未释放此时拿的锁,则会造成死锁产生。
6、线程的安全
1)同步代码块
格式:synchronized(锁对象){具体执行内容},任何对象都可以作为锁对象。
注意:多线程必须使用同一个锁对象,否则不会起到锁的作用
2)同步方法
格式:public synchronized void lock(){}。在非静态时使用的锁对象为this,在静态时使用的锁对象为类名.class
3)显式锁
使用显式锁Lock锁的子类ReentrantLock。
显式锁与隐式锁的区别:
隐式锁不需要自己手动释放,而显式锁需要开发人员在代码中手动释放
7、公平锁与非公平锁
公平锁:多线程排队,先来先使用
非公平锁:抢占式调度,同时竞争cpu资源,竞争到资源的线程执行,其余线程继续等待下一轮的资源争夺,在Java开发中一般使用非公平锁,目的是为了更好的利用资源
8、线程池
因为线程的创建和销毁需要消耗大量时间,故引用线程池对线程进行管理,需要使用线程时直接从线程池中获取使用,线程使用完后对线程进行释放,归还到线程池,由线程池进行统一管理。
1)缓存线程池
线程池中有空闲线程,则直接拿来使用,没有空闲线程则创建新的线程
2)定长线程池
线程池中有空闲线程,则直接拿来使用,没有空闲线程则创建新的线程,当线程池中线程数量达到最大时,则任务等待线程释放再使用
3)单线程线程池
线程池中只有一个线程,空闲则使用,不空闲则任务进行等待
4)期性任务定长线程池
相比较2),增加了定时、间隔执行