线程和进程
什么是线程和进程
进程是程序的一次执行过程,线程是程序更小的执行单位,一个进程执行中可以产生多个线程,不同进程之间很难数据共享,但不同线程之间比较容易共享,进程之间不会互相影响,但是一个线程挂掉会影响整个进程
在Java里启动main函数时就是启动了一个JVM进程,main函数所在的线程就是主线程,一个Java程序的运行时main线程和其他多个线程同时运行
并发和并行的区别
并发:在某一时间段多个任务交替进行(吃饭时停下来打电话),单核cpu执行多任务就是并发
并行:某一时刻多个任务同时进行(边吃饭边打电话)
线程的六(七)种状态
new:初始状态,线程被创建,但还没有调用start方法
runnable:调用了start方法,处在可运行状态,细分为running(运行中)和ready(就绪状态),当线程被调度器选中执行时进入running态,被挂起或者调用yield方法进入ready态
blocked:阻塞状态,表示线程阻塞于锁
waiting:等待状态,表示当前线程需要其他线程的通知或中断
time_waiting:超时等待,表示当前线程在指定的时间自动返回
terminated:表示当前线程执行完毕
上下文切换
CPU时间片从一个任务切换到另一个任务时当前任务会先保存自己的状态,等到切换回来时在加载这个任务的状态,任务从保存到加载就是一次上下文切换上下文切换消耗了大量的CPU时间,也是多线程的问题之一
死锁
比如线程A持有资源一,线程B持有资源二,他们都想申请互相的资源,就都会陷入阻塞进入死锁状态
死锁的条件:
1.互斥:资源在任意一个时刻只由一个资源占用
2.请求与保持:线程在请求其他资源时,不释放已经获得的资源
3.不剥夺条件已获得的资源在不使用时不能被其他线程强行剥夺,只由自己使用完毕后才释放资源
4.循环等待:各个线程之间形成一种头尾相接的等待资源关系
sleep和wait方法的区别和共同点
最大的区别是sleep没有释放锁,而wait释放了,wait常用于线程之间的交互通信,sleep用于暂停执行,wait方法调用后,线程不会自动苏醒,需要其他线程调用notify方法,sleep方法执行完毕后自动苏醒,或者可以使用wait(long time)超时后自动苏醒
为什么不能直接调用run()方法而是调用start()方法
直接执行run方法会把它当成一个main()下的普通每个方法.而不会在某个线程中执行,start方法会执行线程的相应准备工作,使线程进入就绪态,当分配到时间片后开始执行,这是真正的多线程工作
synchronized关键字
synchronized解决的是多个线程之间访问资源的同步性
,它可以保证在其修饰的代码块或资源某一时刻只能有一个资源执行
三种使用方式
1.修饰实例方法,给当前对象加锁
2.修饰静态方法:给当前类加锁
3.修饰代码块:给指定对象或类加锁