-
开启线程的三种方式
- extend Thread
- Implements Runnable
- implements Callable
-
线程和进程的区别
- 进程系统分配最小单元 线程时cpu调度最小单元
- 一个进程至少包含一个线程 或多个线程 线程共享进程资源
- 每个线程都有独立的运行栈和程序计数器,线程切换开销小
-
谈谈volatile关键字的作用
我所理解的保证了变量的可见性。每次读取volatile修饰的变量时都会重新从内存读取
而不是缓存中。
-
谈谈volatile关键字的用法
自己一般用于在多线程中用于某个状态的判断。因为volatile修饰的变量修改后能及时同步到
其他的线程。这里要注意volatile只能保证可见性而不能保证原子性 如果依据volatile 变量的状态
对变量进行写操作,很可能不会依照你想的执行。 因为这里有多个指令,有可能存在同时读到数据
情况,那么第一次写入的值对第二次就不生效了。
-
volatile的原理
这个就要深入到CPU指令了。网上一般的说法是这样的。volatile修饰的变量 写指令后面紧
接着会跟着一个lock指令。这个指令的功能就是通知其他CPU 值已经被更新需要重新获取
-
synchronized 和volatile 关键字的区别
synchronized是一种基于悲观锁同步机制 一旦有线程进入了同步代码块 其他线程就无法进入
在synchronized的代码块里保证了原子性 可见性和有序性,而volatile是一种更轻量级的同步机制
它只是保证了可见性。
-
同一个类里面两个synchronized方法,两个线程同时访问的问题
如果是分别对两个对象的操作 互不影响。
如果对同一个对象操作 首先进入方法的线程回得到this这个锁。只有当这个线程执行完方法释放锁的时候
下一个线程才能得到锁执行方法。
-
static synchronized 方法的多线程访问和作用
是以当前类的Class对象做为锁 也就是该方法最多只能有一个线程在执行
-
run()和start()方法区别
run()方法是Runnable中一个普通的方法 直接调用会在当前线程执行。
start()方法来启动线程,真正实现了多线程运行。 start方法的作用就是将线程由NEW 状态,变为RUNABLE状态。当线程创建成功时,线程处于NEW(新建)状态,如果你不调用 start( )方法,那么线程永远处于NEW状态。调用start( )后,才会变为RUNABLE状态,线程才 可以运行。
synchronized与Lock的区别
类别 | synchronized | Lock |
---|---|---|
存在层次 | Java关键字,jvm层面 | 是一个类 |
锁的释放 | 1. 以获取锁的线程执行完同步代码,释放锁 2线程执行发送异常,jvm会让线程释放锁 | finally中必须释放锁,不然容易造成死锁 |
锁的获取 | ||
锁状态 | 可重入 不可中断非公平 | 可重入,可判断,可公平 |
性能 | 少量同步 | 大量同步 |
- ReentrantLock的内部实现
同步基于volatile 和CAS ,线程阻塞基于Unsafe.park。ReentrantLock基于AQS实现 AQS中维护一个同步队列
Syc继承自AQS,FairSy和NoFairSyn继承自Syc分别代表公平锁和非公平锁的实现机制。
lock方法被调用时如果前面已有线程在run 就会加入到队列tail。unlock被调用时会释放队列head中的线程。