1、启动线程的四种方式 :
- 通过继承Thread类创建线程
- 通过实现Runnable接口创建线程
- 使用Callable和Future创建线程
-
通过线程池启动多线程
https://blog.csdn.net/weixin_41891854/article/details/81265772
2、Thread的几个方法:
- sleep():让线程进入阻塞队列,时间到了之后进入就绪队列
- yield():让出cpu,放弃一次当前的执行进入就绪队列
- join():当前线程进入阻塞队列,直到调用的线程完全执行完之后,唤醒当前线程进入就绪队列
3、synchronized(Object),这里的Object不能是String常量 Integer Long
4、synchronized方法和非synchronized方法是可以同时运行的,比如对一个数据set()方法加synchronized,read()方法不加synchronized,但这种方式会造成脏读。
5、一个同步方法可以调用另一个同步方法,一个线程已经拥有某个对象的锁,再次申请的时候仍然会得到该对象的锁,也就是说synchronized获得的锁是可重入的。这里是继承中有可能发生的情形,子类调用父类的同步方法。
6、程序在执行过程中,如果出现异常,默认情况锁会被释放。
7、synchronized锁升级,synchronized锁对象存在与对象头的MarkWord中,其中有2bit是锁标志位,当只有一个线程时,锁为偏向锁,当有少量个线程时,升级为轻量级锁(自旋锁),当有大量线程访问,并且线程持有锁的时间长时,会向操作系统申请重量级锁,进入等待队列,避免自旋锁空转浪费cpu资源。
https://blog.csdn.net/tongdanping/article/details/79647337
8、volatile的作用:
- 保证线程可见性
- 禁止指令重排序
加了volatile并不能代替synchronized,当有多个线程使用主内存的某个变量时,线程自身的工作区会复制一份主内存的这个变量,volatile只能保证,某个线