1线程的五种状态
创建(new):创建一个线程对象thread t=new thread,是一个对象
就绪状态(Runnable):t.start。调用线程开始方法
运行状态(Running):cpu开始调用处在就绪状态的线程,处于就绪状态的线程,是cpu调动的唯一入口。想要运行线程,必须处于就绪状态。
阻塞状态(Blocked):处于运行状态的线程,因某种原因放弃了对cpu的使用,停止使用,进入到阻塞状态。直到他再次进入到了就绪状态,才会被cpu调用。根据阻塞的原因分为以下三种。
1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
死亡状态(dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
2线程创建的三种方式
1继承thread类
2实现runable接口
3实现callable接口
thread类和runable接口本质都是调用runable方法,但是继承只能单继承,接口却可以多实现,容易扩展。
runable和callable接口相比,callable接口可以返回一个future。
3如何让一个线程按照指定顺序执行
1使用join方法,join方法作用就是阻塞,适用于线程一执行完成后线程二执行才有意义的场景
2使用单线程化线程池
4JMM
指的是java的内存模型
围绕原子性,可见性,有序性来展开
原子性:一个操作不可被分割,要么都执行,要么都不执行。
可见性:一个共享变量如果被某一个线程更改,其他线程是否能够立即知道这个修改。
有序性:线程执行时候可能会发生指令重排。
5线程和进程的区别
一个程序启动时候就算作一个进程,进程相当于一个容器,里面容纳了多个线程
6volatile关键字
volatile关键字用于声明当前数据容易被其他线程修改,只是起到可见性作用,不能保证数据唯一性,如果volatile关键字修饰的数据执行的操作是原子性时候,可以保证不出现脏数据。
7sleep和wait的区别
sleep来自thread类,wait来自object超类
sleep会抛出异常,wait不会
sleep不会释放锁,wait会释放锁
wait只能在同步代码块同步方法块使用,sleep可以在任何地方使用。
8synchronize和lock区别
synchronize是关键字,lock是一个接口
synchronize会自动释放锁,lock只能手动释放
lock会让等待锁的线程中断,synchronize会让线程一直等待下去。
synchronize可以锁住方法代码块等,lock只是范围内。
lock可以知道是否获得锁,synchronize不行。
9 如何停止一个线程
jdk有一个stop方法,但是被标记为过期方法,stop方法过于暴力,立刻停止线程,会产生脏数据,例如存储一个name 张三 sex男,存储到name 张三时候线程被stop,sex存储失败,导致数据丢失。
通常采用interrupt方法对线程进行中断,但是interrupt方法作用只是通知目标线程中断,标识了中断标志位,我们还需要在run方法中对中断标示位进行判断,如果状态位true,手动进行中断操作。(注意事项,如果在sleep状态下被中断,需要处理中断异常,此异常会清除中断标示位,所以需要重新进行中断标识)