Java 并发 同步方案总结
2016-03-06 22:04
513 查看
Synchronized关键字:
实现:利用每个对象的内部锁进行同步;使用1:(下面的await和notifyAll可有可无)
public synchronized void myMethod(){ if(!(ok to process)) await(); //add your code here notifyAll(); }
使用2:(下面的await和notifyAll可有可无)
Object obj = new Object(); public synchronized void myMethod(){ syschronized(obj){ if(!(ok to process)) obj.await(); //add your code here obj.notifyAll(); } }
ReentrantLock类:
使用:Lock mlock = new ReentrantLock(); public void myMethod(){ mlock.lock(); try{ //add your code here } finally{ mlock.unlock(); } }
注意:
锁是可以重入的,一个线程可以重复的获得已经持有的锁;
ReentrantReadWriteLock类:
适用于很多线程从一个数据结构读取数据而很少的线程修改其中数据;使用:
ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); //该锁可以被多个读操作共用的读锁,但会排斥写操作 Lock readLock = rwl.readLock(); //该锁排斥所有其他的读操作和写操作 Lock writeLock = rwl.writeLock(); public int getNumber(){ readLock.lock(); try{ //add your code here } finally{ readLock.unlock(); } } public void setNumber(){ writeLock.lock(); try{ //add your code here } finally{ writeLock.unlock(); } }
Condition条件:(与ReentrantLock配套使用)
使用:Lock mlock = new ReentrantLock(); Condition mCondition = mlock.newCondition(); public void myMethod(){ mlock.lock(); try{ if(!(ok to process)) mConditon.await(); //add your code here mConditon.signalAll(); } finally{ mlock.unlock(); } }
同步器:
Semaphore(信号量):信号量维持一个计数,许可的数目时固定的,由此限制了通过的线程数量;
线程通过调用acquire请求许可,通过release()释放许可;
许可不是必须由获取它的线程释放,任何线程都可以释放任意数目的许可;
CountDownLatch(倒计时门栓):
让一个线程集等待直到计数器变为0;
倒计时门栓是一次性的,一旦计数为0,就不能再重用了;
调用countDown则计数减1;
CyclicBarrier(障栅):
当指定数目的线程都完成了相应的工作后,到达障栅处,此时障栅自动撤销,线程可以继续运行;
使用1
<pre name="code" class="java"> static int data=0; static int nthreads = 10; static CyclicBarrier barrier = new CyclicBarrier(nthreads); public static void main(String[] args) { for(int ii=0;ii<nthreads;ii++){ Runnable myAction = new Runnable(){ public void run(){ //add pre-action data++; try { barrier.await(); System.out.println(data); //add post-action } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }; new Thread(myAction).start(); } }<span style="font-family: 微软雅黑; widows: auto;">//会打印输出10个10;破栅后会执行执行await后面的代码</span>
使用2:
static int data=0; static int nthreads = 10; static Runnable barrierAction = new Runnable(){ @Override public void run() { //add post-action System.out.println(data); } }; static CyclicBarrier barrier = new CyclicBarrier(nthreads,barrierAction); public static void main(String[] args) { for(int ii=0;ii<nthreads;ii++){ Runnable myAction = new Runnable(){ public void run(){ //add pre-action data++; try { barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }; new Thread(myAction).start(); } }//会打印输出1个10<span style="font-family: 微软雅黑; widows: auto;">;破栅后会先执行<span style="widows: auto;">barrierAction的run方法,随后</span>执行await后面的代码</span>
Exchanger(交换器):
两个线程在同一个缓冲区的两个实例上工作;
如一个向缓冲区写,一个从缓冲区读;
当各自完成了各自的工作后交换缓冲区;
SynchronousQueue(同步队列):
实现了BlockingQueue接口
不过它的size永远是0;
调用put方法时将一直阻塞下去,知道另一个线程调用了take方法为止;
Volatile域:
保证读取到的值是当前最新的;用该关键字声明的变量具备可见性;阻塞队列:
java.util.concurrent包下有如下阻塞队列LinkedBlockingQueue:容量没上限,也可指定最大容量,是一个双端的版本
ArrayBlockingQueue:构造时需要指定容量
PriorityBlockingQueue:优先级队列
注意:使用put方法添加元素,使用take方法获取元素,这两个方法是阻塞的
线程安全集合:
java.util.concurrent包下ConcurrentHashMap
ConcurrentSkipListMap
ConcurrentSkipListSet
ConcurrentLinkedQueue
CopyOnWriteArrayList
CopyOnWriteArraySet
Vector
HashTable:key/value均不支持是null
相关文章推荐
- ACM之Java输入输出
- 【JAVA】31、类的定义
- 20145229吴姗珊《JAVA程序设计》第一周学习总结
- Java 二叉树查找算法代码
- 20145212 《Java程序设计》第1周学习总结
- java实现一个过滤器
- Java - 编程基础
- Java Max Direct Memory Size设置
- struts2学习笔记--------为应用指定多个struts文件
- java中四种引用类型
- struts2学习笔记------接受请求参数
- SpringMVC介绍之约定优于配置
- Spring redirect直接返回项目根文件夹
- struts2学习笔记--------动态方法调用和使用通配符定义action
- 随堂笔记160301数组和新特性
- Java大牛养成记(2)——JDBC
- struts2学习笔记--------struts2处理流程
- Web开发学习之路--Springmvc+Hibernate之初体验
- Web开发学习之路--Springmvc+Hibernate之初体验
- struts2学习笔记----------struts2.1.6接收中文请求参数乱码问题