关于学习多线程视频的小结

一、同步方法:
1.在方法上添加synchronize关键字,一个实例一次只有一个线程能够访问
2.不同实例的同步方法,即使在方法上加上synchronize关键字,线程也是各自执行各自的
3.在方法上加上static和synchronize关键字,则全局同步,不论多少个实例,线程都要依次执行

二、同步代码块:
1.在代码块添加synchronize关键字,一个实例一次只有一个线程能够访问
2.如果同步两个代码块,共用一个锁,线程就轮流一个一个执行,两个锁则会并发执行
3.同步代码块时,如果参数为.class对象,则不论多少个实例也要依次进行

三、问题:
1.两个线程访问的一个实例的同步方法,依次执行
2.两个线程访问两个实例的同步方法,并发执行
3.两个线程访问synchronized的静态方法,依次执行
4.同一个实例多线程同时访问同步和非同步,非同步不受到同步的影响,并行执行
5.同一个实例多线程同时访问一个实例的不同同步方法,只能依次进行
6.两个线程访问一个实例的静态同步方法(.class)与非静态同步方法(对象本身),并发执行
7.线程访问同步方法抛出异常后,将会释放锁
8.同步方法里访问不同步方法,这时候也是线程不安全的。
9.锁对象不能为空
10.synchronized作用域不宜过大
11.避免死锁
12.多线程释放锁的时候,jvm如何选择正在等待的锁?与jvm有关
13.synchronized只能一个线程执行,效率低,有什么办法提高性能?减少同步代码的范围,使用其他如读写锁之类的锁
14.怎么灵活的控制锁的获取与释放?可以继承lock接口自己实现

四、核心思想:
1.一个锁只能被一个线程获取,没拿到锁的线程都要等待
2.每个实例都有自己的锁,不同的实例的不同锁互不影响。此外,如果是被static修饰的方法和锁对象为.class的时候所有对象共用一把锁。
3.无论方法是正常执行还是抛出异常,都会释放锁。

五、synchronized锁的性质:
1.可重入(避免死锁,提高封装性)
可重入的三种情况:
1)同一个方法是可重入的
2)可重入不要求是同一个方法
3)可重入不要求是同一个类,如字父类
原理:
由jvm进行跟踪对象被加锁的次数,每次获取锁,计数器加1,每次释放,计数器减1
2.不可中断

六、lock锁:
1.lock锁有锁住和释放两个功能,等价于synchronized关键字。但是如果锁住不释放,则下一个线程没有办法获取锁。

七、jvm是通过monditor进行加锁和解锁的
1.monditorenter的三种情况:
1)锁的计数器为0,这时候线程获取锁,计数器加1
2)可重入的情况,线程继续访问,计数器累加
3)锁的计数器不为0,这时候线程只能等待,发生阻塞的情况
2.monditorenter的两种情况:
1)计数器减1,如果为0,说明该线程已经释放锁了,并且其他被阻塞的线程会继续尝试获取锁
2)计数器减1,如果不为0,说明该线程是可重入进来的,会继续拥有锁

八、synchronized的缺陷:
1.效率低(不如lock)
1) 锁的释放情况少(执行完,异常)
2) 获取锁不能设置超时
3) 不能中断正在尝试获取锁的线程
2.不够灵活(不如读写锁),加锁和释放的时机单一
3.不知道是否成功获取锁(不如lock)

九、注意点:
1.join是将选定的线程加入主线程进行运作,而主线程停止,等待选定的线程运行完才能运作。
2.stop的停止方法现在都不用了,使用stop导致直接终止,没有任何终止信息
3.interrupt不能直接打断线程运行,可设置循环参数isInterrupted,进行打断,但是会跟sleep冲突,所以也不是合适的方法

十、可见性:
1.线程的所有对共享数据的操作应该在线程自己的工作空间内完成,并且不能直接读取主内存。
2.线程之间不能直接交互,需要通过主内存进行交互
3.实现方式
1)synchronized(原子性-同步,可见性)
2)volatile
4.JMM规定,加锁时,会将工作空间的共享数据清除,读取主内存数据;线程解锁前,必须将工作空间数据更新在主内存中。
5.synchronized工作顺序:获取锁,清空工作空间数据,获取主空间数据,工作空间操作数据,工作空间数据拷贝到主空间,释放锁
6.volatile工作顺序:共享数据被访问时,强迫从主空间数据重新获取;而读取的变量改变时,强迫将改变的值刷新到主空间,但是不能保证原子性,对于i++等多步操作无效。

十一、创建线程的两个方法:
1.实现runnable接口,需要创建Thread实例来引用该实现类
2.继承Thread,只要直接创建实例,比实现runnable接口少一步

十二、线程的分类
1.用户线程:前台可见的
2.守护线程:不可见的,用户线程结束后也会跟着结束,setDaemon(true),必须在star钱调用,否则抛出异常。
如数据库连接池的检测线程,jvm启动后的检测线程,垃圾回收线程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章