并发的特性
一、可见性
a、 保证任何一个线程修改变量当即写入到主内存中(堆);
b、 全部线程对该变量引用会强制当即失效,而且该线程必须去堆中获取最新的变量值。编程
二、指令重排序
代码的执行顺序 会在JVM中(编译器优化 指令级并行重排序 内存系统重排序 最终执行的指令序列)安全
三、原子性
同一时刻最多只有一个线程访问该段代码。并发
Volatile -> 可见性、指令重排序ide
Synchronied -> 可见性、指令重排序、原子性性能
lock
存在价值
synchronized只在如下2种状况下会释放锁
1)获取锁的线程执行完了该代码块,而后线程释放对锁的占有;
2)线程执行发生异常,此时JVM会让线程自动释放锁。
所以synchronized可能会形成线程阻塞。
为解决线程阻塞问题,引入此概念。
public interface Lock {
void lock();//获取锁,若是锁被其余线程获取,则进行等待
void lockInterruptibly() throws InterruptedException;
// tryLock()方法是有返回值的,它表示用来尝试获取锁,若是获取成功,则返回true,若是获取失败(即锁已被其余线程获取),则返回 false,也就说这个方法不管如何都会当即返回。在拿不到锁时不会一直在那等待。
boolean tryLock();
//tryLock(long time, TimeUnit unit)方法和tryLock()方法是相似的,只不过区别在于这个方法在拿不 到锁时会等待必定的时间,在时间期限以内若是还拿不到锁,就返回false。若是若是一开始拿到锁或者在等待期间内拿到了锁,则返回true。
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock(); //释放锁
Condition newCondition();
}优化
Final
final修饰的变量不可改变,在并发编程场景下性能突出。线程
volatile和synchronied区别
一、volatile不会形成线程的阻塞,而synchronized可能会形成线程的阻塞。(原子性差别形成)
二、volatile只能修饰变量,而synchronized则能够修饰变量和方法。
三、当一个域的值依赖于它以前的值时,volatile就没法工做了,如n=n+1,n++等。若是某个域的值受到其余域的值的限制,那么volatile也没法工做,如Range类的lower和upper边界,必须遵循lower<=upper的限制。
四、使用volatile而不是synchronized的惟一安全的状况是类中只有一个可变的域。排序
synchronized和lock区别
1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
2)synchronized在发生异常时,会自动释放线程占有的锁,所以不会致使死锁现象发生;而Lock在发生异常时,若是没有主动经过unLock()去释放锁,则极可能形成死锁现象,所以使用Lock时须要在finally块中释放锁;
3)Lock可让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不可以响应中断;
4)经过Lock能够知道有没有成功获取锁,而synchronized却没法办到。
5)Lock能够提升多个线程进行读操做的效率。
在性能上来讲,若是竞争资源不激烈,二者的性能是差很少的,而当竞争资源很是激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。因此说,在具体使用时要根据适当状况选择。接口