在并发要想正确执行须要三要素
Synchronized关键字
synchronized有加锁的做用,全部的synchronized修饰方法都会顺序执行(占用CPU的顺序)
当synchronized关键字修饰静态方法(static)时升级为类锁,若是不是静态方法两个对象之间没有关系
- Synchronized关键字执行方式
- 首先尝试得到锁
- 若是得到锁,则执行synchronized方法体的内容
- 若是没有得到锁则等待释放锁,并不断尝试得到锁,一旦锁被释放,多个线程会去尝试得到锁,形成锁竞争
- 锁竞争问题,若是在高并发,线程数量高,则会引发CPU占用高,或者直接宕机
- 对象锁同步异步问题?
- 对象锁之针对synchronized方法生效,对象中全部的synchronized方法都会同步执行,而非synchronized关键字修饰的方法则异步执行
- 类中有两个synchronized方法,两个线程同时调用两个方法,相互之间是有锁竞争关系的,由于两个方法属于一个对象,咱们加的是对象锁
- 脏读
- 因为同步与异步执行的个性,若是不从全局考虑,就很容易引发数据的不一致,这就是脏读
- 多线程访问同一个资源,在线程修改数据的过程当中,有另外的数据来读取数据,就会引起脏读
- 为了不脏读咱们必定要肯定修改数据的原子性,而且对读取数据进行同步控制
Synchronized代码块
-
能够作更细粒度的
-
能够作对象锁
-
能够作类锁
-
能够任意对象锁
-
同类型锁互斥,不一样类型锁互不干扰
-
不要在线程内部修改锁的引用,引用改变会致使锁失效,在线程中修改锁的属性而不修改锁的引用则不会失效,不会产生线程安全问题
-
同一个对象内的多个synchronized方法能够锁重入 父子类方法也能够锁重入
-
-
一个线程在得到锁之后执行操做,发生错误抛出异常,则自动释放锁
-
能够利用抛出异常主动释放锁
-
程序异常时主动抛出异常防止死锁,没法释放
-
若是非主动抛出异常而是程序错误抛出的异常释放锁可能致使不一致
是指两个进程或以上的进程在执行过程当中,因为竞争资源或者因为彼此通讯而形成的一种堵塞现象,若无外力做用,他们都将没法推动下去,
每一个线程都是独立的运行个体,线程通讯能让多个线程协同合做
Object类中wait与notify方法能够实现线程通信
wait与notify必须与synchronized一同使用
wait是释放锁的,notify是不释放锁的
Notify只会通知一个wait中的线程,并把锁给他不会产生锁竞争问题可是该线程完成以后必须再次notify或者notifyAll,完成相似链式操做
notifyAll 会通知全部的wait中的线程,会产生锁竞争