“非线程安全”问题存在于“实例变量”中,若是是方法内部的私有变量,则不存在线程安全问题。这是由于方法内部的变量都是私有形成的。java
synchronized 获取的都是对象锁。若是多个线程访问多个对象,则JVM会建立多个锁。安全
A线程持有object 对象的的Lock锁,B线程能够异步调用A线程非同步方法。A线程持有object 对象的的Lock锁,B线程若是在这个时调用object对象中的synchronized类型的方法则须要等待。多线程
synchronized拥有锁重入的功能。当一个线程获得一个对象锁后,再次请求对象锁时是能够再次获得该对象的锁。异步
可重入锁支持在父子类继承的环境中。工具
当一个线程出现异常,其持有的锁自动释放。this
同步不具备继承。线程
synchronized(非this对象)同步代码块格式时,持有不一样的对象监视器是异步的效果。对象
synchronized还能够做用在static静态方法上,那是对*.java文件对应的Class类进行加锁。继承
使用JDK自带工具查看线程是否死锁:进入JDK安装目录,bin目录下,执行jps命令。再执行jstack -l xxx 。内存
volatile 是变量在多个线程可见。强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值。
volatile不支持原子性。
volatile vs sysnchronized:
变量在内存中的过程:
执行完同步代码就会释放对象的锁;在执行同步代码的过程当中,遇到异常而致使线程终止,锁也会被释放;在执行同步代码的过程当中,执行了锁对象所属的wait()方法,这个线程会释放锁对象,而此线程对象会进入线程等待池中等待唤醒。
join()的做用是等待线程对象销毁。在内部使用wait()方法进行等待。
join(long) vs sleep:前者在指定时间后会释放锁,然后者不会。
ThreadLocal 解决的是变量在不一样线程之间的隔离性。
InheritableThreadLocal 能够在子线程中取得父线程继承下来的值。
Lock.getHoldCount()方法能够查询当前线程保持此锁定的个数,即调用lock方法的次数;getQueueLength()返回正等待获取此锁定的线程估计数;getWaitQueueLength(Condition condition)返回等待与此锁定相关的给定条件condition的线程估计数。
其余方法:
condition.awaitUntil(xxx):设置线程特定时间后自动唤醒。在等待中,能够被其余线程提早唤醒。
ReentrantReadWriteLock:多个线程可读,一个线程写。该锁维护2个锁,一个读锁,也称为共享锁,一个写入锁,也称为拍他锁。多个读锁之间不互斥,读锁写锁互斥,写锁与写锁互斥。