多线程

一、线程的创建

1.通过Thread类对象创建
2.新建一个类继承Thread创建对象
3.新建一个类实现Runnable接口
4.通过线程池创建线程 excutor
5.通过callable接口来创建线程

二、线程状态

1.new
2.Runable\Block\Waiting\Time Waiting
3.Terminate
4.note:[1]若需要线程执行完成之后再执行其他功能使用 join();方法实现。
[2]线程结束状态
1)线程正常终止:run()方法执行到return语句返回;
2)线程意外终止:run()方法因为未捕获的异常导致线程终止
3)对某个线程的Thread实例调用stop()方法强制终止(强烈不推荐使用)

三、中断线程 --Interrupter

1.中断线程需要用到线程对象的Interrupter()方法。当执行到循环的时候做出isInterrupter方法,
2.当涉及到多个线程时使用标志位置方法。这是对共享变量需要在自己的写的线程中定义静态变量 用volatile修饰
volatile作用:每次访问变量时,总是获取主内存的最新值;每次修改变量后,立刻回写到主内存

四、守护线程 --deamThread

1.守护线程是为其他线程服务的线程;
2.所有非守护线程都执行完毕后,虚拟机退出;
3.守护线程不能持有需要关闭的资源(如打开文件等)。

五、线程同步

1.取两个线程对同一变量进行单增10000次,单减10000次 最后结果应该是0,但结果不是0
原因是:n = n + 1; 执行了ILOAD IADD ISTORE ,多线程状态下的ILOAD获取不是按照某一线程执行完成后再执行其他操作。
总的来讲是没有保证代码的原子性操作
2.多线程同时读写共享变量时,会造成逻辑错误,因此需要通过synchronized同步
3.对JVM定义的单个原子操作不需要同步。(基本类型(long和double除外),引用类型赋值 List<string> list = anotherList)</string>

六、同步方法

1.同步方法中this应用
2.通过合理的设计和数据封装可以让一个类变为“线程安全”

七、死锁

Java的synchronized锁是可重入锁,
死锁产生的条件是多线程各自持有不同的锁,并互相试图获取对方已持有的锁,导致无限等待。避免死锁的方法是多线程获取锁的顺序要一致。

八、使用wait和notify

1.在synchronized内部可以调用wait()使线程进入等待状态。必须在已获得的锁对象上调用wait()方法;
2.在synchronized内部可以调用notify()或notifyAll()唤醒其他等待线程。必须在已获得的锁对象上调用notify()或notifyAll()方法。

九、使用ReentrantLock 可重复锁

1.公平锁和非公平锁
2.ReentrantLock可以替代synchronized进行同步,且ReentrantLock获取锁更安全;
3.必须先获取到锁,再进入try {…}代码块,最后使用finally保证释放锁;可以使用tryLock()尝试获取锁。

十、condition