什么是线程:一个程序执行多个任务,每一个人任务称为一个线程.多线程程序是能够同时运行多个一个以上的线程的程序. java
具体理解:同一时间运行多个线程,多个线程对同一数据资源进行处理,可能会形成数据的失真性,具体例子参考:<java核心技术.卷一>P640页银行转钱问题.由于对线程的管理不当,形成数据的错误.因此出现了一系列操做管理线程的技巧. 安全
一.线程同步 多线程
1.锁对象 并发
有两种机制防止代码受并发访问的干扰,java提供了synchronized关键字,和java5.0 app
引入的ReentrantLock类(做用:构建一个能够用来被保护临界区的可重入锁). spa
ReentrantLock保护代码块的基本结构以下: 线程
private Lock mylock = new ReentrantLock(); mylock.lock(); try { }finally { mylock.unlock(); }
把解锁操做放到finally句子里,防止在临界区的代码抛出异常,锁必须被释放,不然,线程永远被阻塞. 设计
或许又想,若是建立多个对象,多个对象获得不一样的锁对象,多个线程都不会发生阻塞? code
锁是可重入的,由于线程能够重复的得到已经持有的锁.锁保持一个持有计数来跟踪对lock方法的嵌套调用.而且lock()方法的做用是获取这个锁,若是同时被另外一个线程拥有则发生阻塞. orm
2.条件对象:
线程进入临界区,却发如今某一个条件知足后他才能执行.要使用一个条件对象来管理已经得到了一个锁可是却不能作有用工做的线程.
private Lock mylock = new ReentrantLock(); private Condition condition = myLock.newCondition(); // 得到条件对象
说白了就是ReentrantLock只能锁住线程,条件对象能够对线程进行一些操做,如await()将进程放到条件等待集中,signallAll()解除该条件等待集中的全部线程的阻塞状态,signal()从条件等待集中随机选择一个线程,解除阻塞状态.
3.synchronized关键字
同步阻塞:
private Object lock = new Object(); // 经过一个对象锁来实现额外的原子操做 synchronized (lock) { // 多个线程不能共同访问synchronized块内容,同一时刻只有一个线程能访问 lock.notifyAll(); // 唤醒其余线程继续竞争synchronized块内容 }
4.volatile
volatile是一个类型修饰符。它是被设计用来修饰被不一样线程访问和修改的变量.volatile保证了线程能够正确的读取其余线程的写入的值,可见ref JMM happens-before原则,多个线程能够共同访问这个类型变量的内容.
5.读写锁
java.util.concurrent.Locks定义了两个锁类:ReentrantReadWriteLock和ReentrantLock.
// 构造一个ReentrantReadWriteLock对象 private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); // 抽取读锁和写锁 private Lock readLock = rwl.readLock(); private Lock writeLock = rwl.writeLock(); // 对全部获取方法加读锁: public double getXXX() { readLock.lock(); try { } finally { readLock.unLock(); } } // 对全部修改方法加写锁: public double setXXX() { writeLock.lock(); try { } finally { writeLock.unLock(); } }
Lock readLock() // 获得一个能够被多个读操做共用的读锁,排斥全部写操做.
Lock writeLock() // 获得一个写锁,排斥全部其余的读操做和写操做
二.阻塞队列:
阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操做将会被阻塞,或者当队列是满时,往队列里添加元素的操做会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其余的线程往空的队列插入新的元素。一样,试图往已满的阻塞队列中添加新元素的线程一样也会被阻塞,直到其余的线程使队列从新变得空闲起来.
三.线程的安全集合
四.执行器:
线程池
五.同步器: