Java并发编程总结(一)
2016-06-24 00:00
483 查看
摘要: 本文将总结性的介绍Java并发编程核心方法和框架
首先纠正众多朋友的一个错误,线程同步机制并不是只有synchronized关键字才能实现。还可以有Semaphore、Lock及其实现类ReentrantLock
多线程中线程的同步概念其实是排着队去执行一个任务,执行任务时一个一个执行,并不能并行执行,这样的有点是有助于程序逻辑的正确性,不会出现非线程安全安全问题,保证软件系统功能上的运行稳定性。
1、Semaphore,此类的主要作用是限制线程并发的数量,如果不限制线程并发数量,则CPU的资源就很快耗尽,每个线程执行任务是相当缓慢的,因为CPU要把时间片分配给不同的线程对象,而且上下文切换也要耗费时间,最终造成系统运行效率大幅减低,所以限制线程并发很有必要。Semaphore类发放许可的计算方式是减法操作。构造参数permits是许可的意思,代表同一时间内,最多允许多少个线程同时执行acquire()和release()之间的代码。无参数方法acquire()的作用是使用1个许可,是减法操作。Semaphore类的方法示意图
2、Exchanger,类Exchanger作用是可以使两个线程之间传输数据。比wait/notify要更加方便。Exchanger类的作用与结构相当简单,主要学习就是exchange()方法。类Exchanger中的exchange()方法具有阻塞的特色,也就是此方法别调用后等待其他线程来取得数据,如果没有其他线程取得数据,则一直阻塞等待。
3、CountDownLatch,同步功能辅助类,使用效果是给定一个计数,当使用这个CountDownLatch类的线程判断计数不为0时,则呈await()和countDown()方法来进行。实现等待与继续运行的效果分别需要使用await()和countDown()方法来执行。调用await()方法时判断计数是否为0,如果不为0,则呈等待状态,其他线程调用countDown()方法将计数减1,当计数减到0时,呈等待的线程继续运行。getCount()是获取当前的计数个数。。要说明的是,计数无法被重置,如果需要重置计数,请考虑使用CyclicBarrier类。
4、CyclicBarrier不仅有CountDownLatch所具有的功能,还可以实现屏障等待的功能,也就是阶段性同步,它在使用上的意义在于可以循环实现线程要一起做任务的目标,不是像CountDownLatch一样,仅仅支持一次线程与同步点阻塞的特性。它允许一组线程相互等待,直到达到某个公共屏障点,这些线程必须实时相互等待。方法reset()的作用是重置屏障。
代码示例
5、Phaser类,CyclicBarrier类本身还有一些缺陷,比如不可动态添加parties计数,调用一次await()方法仅仅占用1个parties计数,所以在JDK7中新增了一个名为Phaser的类来解决这样的问题。Phaser类提供了动态增加parties计数,这点比CyclicBarrier类操作parties更加方便,通过若干个方法来控制多个线程之间同步运行的效果,还可以实现针对某一个线程取消同步运行的效果,而且支持在指定屏障处等待,在等待时还支持中断和非中断等功能。使用Java并发类对线程进行分组同步控制时,Phaser比CyclicBarrier类功能更加强大。Phaser类的方法示意图如下:
首先纠正众多朋友的一个错误,线程同步机制并不是只有synchronized关键字才能实现。还可以有Semaphore、Lock及其实现类ReentrantLock
多线程中线程的同步概念其实是排着队去执行一个任务,执行任务时一个一个执行,并不能并行执行,这样的有点是有助于程序逻辑的正确性,不会出现非线程安全安全问题,保证软件系统功能上的运行稳定性。
1、Semaphore,此类的主要作用是限制线程并发的数量,如果不限制线程并发数量,则CPU的资源就很快耗尽,每个线程执行任务是相当缓慢的,因为CPU要把时间片分配给不同的线程对象,而且上下文切换也要耗费时间,最终造成系统运行效率大幅减低,所以限制线程并发很有必要。Semaphore类发放许可的计算方式是减法操作。构造参数permits是许可的意思,代表同一时间内,最多允许多少个线程同时执行acquire()和release()之间的代码。无参数方法acquire()的作用是使用1个许可,是减法操作。Semaphore类的方法示意图
2、Exchanger,类Exchanger作用是可以使两个线程之间传输数据。比wait/notify要更加方便。Exchanger类的作用与结构相当简单,主要学习就是exchange()方法。类Exchanger中的exchange()方法具有阻塞的特色,也就是此方法别调用后等待其他线程来取得数据,如果没有其他线程取得数据,则一直阻塞等待。
3、CountDownLatch,同步功能辅助类,使用效果是给定一个计数,当使用这个CountDownLatch类的线程判断计数不为0时,则呈await()和countDown()方法来进行。实现等待与继续运行的效果分别需要使用await()和countDown()方法来执行。调用await()方法时判断计数是否为0,如果不为0,则呈等待状态,其他线程调用countDown()方法将计数减1,当计数减到0时,呈等待的线程继续运行。getCount()是获取当前的计数个数。。要说明的是,计数无法被重置,如果需要重置计数,请考虑使用CyclicBarrier类。
4、CyclicBarrier不仅有CountDownLatch所具有的功能,还可以实现屏障等待的功能,也就是阶段性同步,它在使用上的意义在于可以循环实现线程要一起做任务的目标,不是像CountDownLatch一样,仅仅支持一次线程与同步点阻塞的特性。它允许一组线程相互等待,直到达到某个公共屏障点,这些线程必须实时相互等待。方法reset()的作用是重置屏障。
代码示例
[code=language-java]package org.jf.biz; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierTest { /** * 创建内部类,实现线程 * */ class MyThread extends Thread{ private CyclicBarrier cbRef; public MyThread(CyclicBarrier cbRef) { super(); this.cbRef = cbRef; } @Override public void run() { try { Thread.sleep((int) Math.random() * 1000); System.out.println(Thread.currentThread().getName() + "到了,到达时间:" +System.currentTimeMillis()); cbRef.await(); } catch (InterruptedException | BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { // TODO 这段代码的作用是设置最大为5个的parties同行者, //也就是说5个线程都执行了cbRef对象的await()方法后程序才继续向下进行 CyclicBarrier cbRef = new CyclicBarrier(5, new Runnable() { @Override public void run() { // TODO Auto-generated method stub System.out.println("全都到齐了,进行下一步动作"); } }); CyclicBarrierTest.MyThread[] threadArray = new MyThread[5]; for (int i = 0; i < threadArray.length; i++) { CyclicBarrierTest test = new CyclicBarrierTest(); CyclicBarrierTest.MyThread thread = test.new MyThread(cbRef); threadArray[i] = thread; } for (MyThread myThread : threadArray) { myThread.start(); } } }
5、Phaser类,CyclicBarrier类本身还有一些缺陷,比如不可动态添加parties计数,调用一次await()方法仅仅占用1个parties计数,所以在JDK7中新增了一个名为Phaser的类来解决这样的问题。Phaser类提供了动态增加parties计数,这点比CyclicBarrier类操作parties更加方便,通过若干个方法来控制多个线程之间同步运行的效果,还可以实现针对某一个线程取消同步运行的效果,而且支持在指定屏障处等待,在等待时还支持中断和非中断等功能。使用Java并发类对线程进行分组同步控制时,Phaser比CyclicBarrier类功能更加强大。Phaser类的方法示意图如下:
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树