Executor
execute(Runnable command);
ExecutorService
interface ExecutorService extends Executor
<T> Future<T> submit(Callable<T> task); Future<?> submit(Runnable task); <T> Future<T> submit(Runnable task, T result); ...
Future
FutureTask
public class FutureTask<V> extends Object implements Future<V>, Runnable
FutureTask(Callable<V> callable) //创建一个 FutureTask,一旦运行就执行给定的 Callable。 FutureTask(Runnable runnable, V result) //创建一个 FutureTask,一旦运行就执行给定的 Runnable,并安排成功完成时 get 返回给定的结果 。
CompletionService
//能够拿到最先完成的任务的返回值,而不管它们加入线程池的顺序
Future<V> submit(Callable<V> task); Future<V> submit(Runnable task, V result);
CyclicBarrier
//它允许一组线程互相等待,直到到达某个公共屏障点
//线程分别执行,互不影响,执行到barrier.await();时该线程进入等待状态,当几个线程都执行到barrier.await();时,达到CyclicBarrier启动所需的阻塞线程数,进入到new CyclicBarrier(2, new Runnable()...)里面的方法, 执行完里面的方法后,等待的两个线程再次被唤醒,继续各自执行线程后面的语句
CyclicBarrier(int parties) CyclicBarrier(int parties, Runnable barrierAction)
await()
Semaphore
//控制某个资源可被同时访问的个数
Semaphore(int permits) Semaphore(int permits, boolean fair)
acquire() // 获取许可
release() //访问完后释放
CountDownLath
//可用于在一批线程中,在每个线程中countDown(),在外部调用一次await(),使得各线程完成后再执行后面代码
CountDownLatch(int count)
await() //阻塞所有线程,直到其count为0
countDown() //计数器减一
AbstractQueuedSynchronizer的介绍和原理分析
AbstractQueuedSynchronizer百度百科
源码分析 一 AbstractQueuedSynchronizer
Inside AbstractQueuedSynchronizer (1)
ReentrantLock代码剖析之ReentrantLock.lock
JAVA并发-自旋锁、排队自旋锁、MCS锁、CLH锁(注意其他文章)
Example1:
利用ThreadGroup等待所有线程执行结束
public class T { public static void main(String[] args) { ThreadGroup group1 = new ThreadGroup("group-one"); for(int i=1; i<=10; i++){ new Thread(group1, new GroupThreadMem(),i+"#线程").start(); } while(group1.activeCount() > 0){ System.out.println("group1的当前的活跃数量:"+group1.activeCount()); } System.out.println("==group1中所有线程执行结束==="); } } class GroupThreadMem implements Runnable { @Override public void run() { int times = new Random().nextInt(10); while(times-- > 0){ try { Thread.sleep(50); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } }
Example2:
实例模拟ReentrantLock、synchronized、ReentrantReadWriteLock三种锁在不同场景下的性能情况
代码搞起:
import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class CurrentObject { private static Random random = new Random(); public final static int READ_NUM = 180;// 读线程数 public final static int WRITE_NUM = 20;// 写线程数 private int value;//并发需要读写的值 private ReadWriteLock lock = new ReentrantReadWriteLock(); private Lock locknew = new ReentrantLock(); //------------------------------------------------------------- /** * 通过ReentrantReadWriteLock添加读锁 * @return value * {@link ReentrantReadWriteLock} */ public int getValueLock() { lock.readLock().lock(); try { return value; } finally { lock.readLock().unlock(); } } /** * 通过ReentrantReadWriteLock添加写锁 * @param value */ public void setValueLock(int value) { lock.writeLock().lock(); try { this.value = value; } finally { lock.writeLock().unlock(); } } //------------------------------------------------------------- /** * 通过ReentrantLock添加读锁 * @return value */ public int getValueNew() { locknew.lock(); try { return value; } finally { locknew.unlock(); } } /** * 通过ReentrantLock添加写锁 * @param value */ public void setValueNew(int value) { locknew.lock(); try { this.value = value; } finally { locknew.unlock(); } } //------------------------------------------------------------- /** * 通过synchronized添加读锁 * @return value */ public synchronized int getValueSyn() { return value; } /** * 通过synchronized添加写锁 * @param value */ public synchronized void setValueSyn(int value) { this.value = value; } //------------------------------------------------------------- /** * 用于读/写平均耗时的展现 */ public static void display() { System.out.println("读平均耗时:" + (TimeCostUtils.getReadLong().get() / READ_NUM) + " ns"); System.out.println("写平均耗时:" + (TimeCostUtils.getWriteLong().get() / WRITE_NUM) + " ns"); } /** * 测试方法 * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { final CurrentObject concurrentObject = new CurrentObject(); //防止线程池大小过大,CPU过多的上下文切换导致的开销影响,线程池大小必须同总共开启的对象 int maxProcessor = READ_NUM + WRITE_NUM; final ExecutorService newFixedThreadPool = Executors .newFixedThreadPool(maxProcessor); final CountDownLatch latch = new CountDownLatch(READ_NUM + WRITE_NUM);// 最后关闭线程池 final CyclicBarrier barrier = new CyclicBarrier(READ_NUM + WRITE_NUM);// 等待所有线程启动后并发读写 for (int i = 0; i < READ_NUM; i++) { newFixedThreadPool.execute(new Runnable() { @Override public void run() { try { barrier.await(); } catch (Exception e) { e.printStackTrace(); } TimeCostUtils.start(TimeCostUtils.READ); concurrentObject.getValueLock(); //concurrentObject.getValueNew(); //concurrentObject.getValueSyn(); TimeCostUtils.end(); latch.countDown(); } }); } for (int i = 0; i < WRITE_NUM; i++) { newFixedThreadPool.execute(new Runnable() { @Override public void run() { int nextInt = random.nextInt(1000); try { barrier.await(); } catch (Exception e) { e.printStackTrace(); } TimeCostUtils.start(TimeCostUtils.WRITE); concurrentObject.setValueLock(nextInt); //concurrentObject.setValueNew(nextInt); //concurrentObject.setValueSyn(nextInt); TimeCostUtils.end(); latch.countDown(); } }); } latch.await(); newFixedThreadPool.shutdown(); // 系统退出前,关闭线程池及计算平均耗时、总耗时 Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { @Override public void run() { display(); } })); } }
import java.util.concurrent.atomic.AtomicLong; public class TimeCostUtils { private static AtomicLong readLong = new AtomicLong(); private static AtomicLong writeLong = new AtomicLong(); public final static String WRITE = "write"; public final static String READ = "read"; static ThreadLocal<TimesRecords> recordMap = new ThreadLocal<TimesRecords>(); public static void start(String prefix) { TimesRecords timesRecords = new TimesRecords(prefix, System.nanoTime()); recordMap.set(timesRecords); } public static void end() { TimesRecords timesRecords = recordMap.get(); long cost = System.nanoTime() - timesRecords.getCost(); // 计算每次的开销时间 if (timesRecords.getName().equals(WRITE)) { writeLong.addAndGet(cost); } else { readLong.addAndGet(cost); } } public static AtomicLong getReadLong() { return readLong; } public static AtomicLong getWriteLong() { return writeLong; } static class TimesRecords { private String name; private long cost; public TimesRecords(String name, long cost) { this.name = name; this.cost = cost; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getCost() { return cost; } public void setCost(long cost) { this.cost = cost; } } }
结果:
1、ReentrantReadWriteLock
读平均耗时:93373 ns
写平均耗时:562068 ns
2、ReentrantLock
读平均耗时:32015 ns
写平均耗时:7053 ns
3、Synchoroniced
读平均耗时:39913 ns
写平均耗时:6760 ns
相关推荐
资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著 结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 Java多线程无处不在,如...
JAVA 多线程总结 扩展java lang Thread类 实现java lang Runnable接口
线程调度是值按照特定的机制为多个线程分配CPU的使用权。 调度的模式有两种:分时调度和抢占式调度。分时调度是所有线程轮流获得CPU使用权,并平均分配每个线程占用CPU的时间;抢占式调度是根据线程的优先级别来获取...
《JAVA多线程设计模式》PDF 下载 《Java线程 高清晰中文第二版》中文第二版(PDF) 前言 第一章 线程简介 Java术语 线程概述 为什么要使用线程? 总结 第二章 Java线程API 通过Thread类创建线程 使用Runable接口...
资源包含以下内容: Java 线程及进程 Java 中的线程类(Thread) Java 中的 Runnable 接口 两种实现多线程方式的对比分析 Java 中线程的同步
Java语言的多线程需要操作系统的支持。 Java 虚拟机允许应用程序并发地运行多个执行线程。Java语言提供了多线程编程的扩展点,并给出了功能强大的线程控制API。 在Java中,多线程的实现有两种方式: 扩展...
二、Java与多线程 Java语言的多线程需要操作系统的支持。 Java 虚拟机允许应用程序并发地运行多个执行线程。Java语言提供了多线程编程的扩展点,并给出了功能强大的线程控制API。 在Java中,多线程的实现有两...
重点回顾 练习问题 Introduction 2 多线程程序的评量标准 多线程程序的评量标准 安全性——不损坏对象 生存性——进行必要的处理 复用性——可再利用类 性能——能快速、大量进行处理 评量标准的总结 重点回顾 练习...
看完《think in java》多线程章节,自己写的多线程文档,还结合了其他的相关网络资料。 线程 一. 线程池 1)为什么要使用线程池 2 2)一个具有线程池的工作队列 3 3)使用线程池的风险: 4 4)有效使用线程池的原则 5...
这个包是张孝祥老师关于线程这块的总结,里面的内容是多线程的所有内容,各种类的实例,掌握这些代码可以让你从线程跳跃一个等级,记得好评哦!
MFC中有两类线程,分别称之为工作者线程和用户界面线程。二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环。 工作者线程没有消息机制,通常用来执行后台计算和维护任务,如...
目前任务需要做一个界面程序,PyQt是非常方便的选择,QT丰富的控件以及python方便的编程。近期遇到界面中执行一些后台任务...– PyQt5.QtCore 核心功能类,如QT,QThread,pyqtSignal – PyQt5.QtGui UI类,如QFont –
【2018最新最详细】并发多线程教程,课程结构如下 1.并发编程的优缺点 2.线程的状态转换以及基本操作 3.java内存模型以及happens-before规则 4.彻底理解synchronized 5.彻底理解volatile 6.你以为你真的了解final吗...
参加工作以来,我编写并维护了若干C++/Java多线程网络服务程序,这本书总结了我在开发维护这类服务程序方面的经验。工作中,我没有写过单线程的网络服务程序,没有写过C语言的网络服务程序,也没有写过运行在Windows...
C++拔尖总结——多线程,维护,变量,函数,类,STL,网络基础,认识类,设计类,模板编译,linux结合,makefile等等,适用于已就业1-2年的像突破瓶颈期的新成员C++高级总结
类,接口,委托,多线程, 泛型,设计模式 非常适合初学者
在多线程编程这块,我们经常要使用Handler(处理),Thread(线程)和Runnable这三个类,那么他们之间的关系你是否弄清楚了呢? 首先说明Android的CPU分配的最小单元是线程,Handler一般是在某个线程里创建的,因而...
Android 多线程的实例详解 Java多线程方式 1. 继承Thread线程,实现run方法 2. 实现Runnable接口 JAVA单继承性,当我们想将一个已经继承了其他类的子类放到Thread中时,单继承的局限就体现出来了 但是可以实现...
我们知道,多线程是Android开发中必现的场景,很多...Thread是Java中实现多线程的线程类,每个Thread对象都可以启动一个新的线程,注意是可以启动,也可以不启动新线程: thread.run();//不启动新线程,在当前线程执行
Java中可以通过Thread类和Runnable接口来创建多个线程,线程拥有五种状态,下面我们就来简单总结Java中线程的状态及多线程的实现方式: