线程同步工具(五)运行阶段性并发任务

声明:本文是《 Java 7 Concurrency Cookbook 》的第三章, 作者: Javier Fernández González 译者:郑玉婷

运行阶段性并发任务

Java 并发 API 提供的一个非常复杂且强大的功能是,能够使用Phaser类运行阶段性的并发任务。当某些并发任务是分成多个步骤来执行时,那么此机制是非常有用的。Phaser类提供的机制是在每个步骤的结尾同步线程,所以除非全部线程完成第一个步骤,否则线程不能开始进行第二步。

相对于其他同步应用,我们必须初始化Phaser类与这次同步操作有关的任务数,我们可以通过增加或者减少来不断的改变这个数。

在这个指南,你将学习如果使用Phaser类来同步3个并发任务。这3个任务会在3个不同的文件夹和它们的子文件夹中搜索扩展名是.log并在24小时内修改过的文件。这个任务被分成3个步骤:

1. 在指定的文件夹和子文件夹中获得文件扩展名为.log的文件列表。
2. 过滤第一步的列表中修改超过24小时的文件。
3. 在操控台打印结果。

在步骤1和步骤2的结尾我们要检查列表是否为空。如果为空,那么线程直接结束运行并从phaser类中淘汰。 阅读全文

线程同步工具(四)在同一个点同步任务

声明:本文是《 Java 7 Concurrency Cookbook 》的第三章, 作者: Javier Fernández González 译者:郑玉婷

在同一个点同步任务

Java 并发 API 提供了可以允许2个或多个线程在在一个确定点的同步应用。它是 CyclicBarrier 类。此类与在此章节的等待多个并发事件完成指南中的 CountDownLatch 类相似,但是它有一些特殊性让它成为更强大的类。

CyclicBarrier 类有一个整数初始值,此值表示将在同一点同步的线程数量。当其中一个线程到达确定点,它会调用await() 方法来等待其他线程。当线程调用这个方法,CyclicBarrier阻塞线程进入休眠直到其他线程到达。当最后一个线程调用CyclicBarrier 类的await() 方法,它唤醒所有等待的线程并继续执行它们的任务。

CyclicBarrier 类有个有趣的优势是,你可以传递一个外加的 Runnable 对象作为初始参数,并且当全部线程都到达同一个点时,CyclicBarrier类 会把这个对象当做线程来执行。此特点让这个类在使用 divide 和 conquer 编程技术时,可以充分发挥任务的并行性,

在这个指南,你将学习如何使用 CyclicBarrier 类来让一组线程在一个确定点同步。你也将使用 Runnable 对象,它将会在全部线程都到达确定点后被执行。在这个例子里,你将在数字矩阵中查找一个数字。矩阵会被分成多个子集(使用divide 和 conquer 技术),所以每个线程会在一个子集中查找那个数字。一旦全部行程运行结束,会有一个最终任务来统一他们的结果。 阅读全文

线程同步工具(三)等待多个并发事件完成

声明:本文是《 Java 7 Concurrency Cookbook 》的第三章, 作者: Javier Fernández González 译者:郑玉婷

等待多个并发事件完成

Java并发API提供这样的类,它允许1个或者多个线程一直等待,直到一组操作执行完成。 这个类就是CountDownLatch类。它初始一个整数值,此值是线程将要等待的操作数。当某个线程为了想要执行这些操作而等待时, 它要使用 await()方法。此方法让线程进入休眠直到操作完成。 当某个操作结束,它使用countDown() 方法来减少CountDownLatch类的内部计数器。当计数器到达0时,这个类会唤醒全部使用await() 方法休眠的线程们。

在这个指南,你将学习如果使用 CountDownLatch 类来实现 video- conference 系统。 video-conference 系统将等待全部参与者到达后才会开始。 阅读全文

线程同步工具(二)控制并发访问多个资源

声明:本文是《 Java 7 Concurrency Cookbook 》的第三章, 作者: Javier Fernández González 译者:郑玉婷

控制并发访问多个资源

在并发访问资源的控制中,你学习了信号量(semaphores)的基本知识。

在上个指南,你实现了使用binary semaphores的例子。那种semaphores是用来保护访问一个共享资源的,或者说一个代码片段每次只能被一个线程执行。但是semaphores也可以用来保护多个资源的副本,也就是说当你有一个代码片段每次可以被多个线程执行。

在这个指南中,你将学习怎样使用semaphore来保护多个资源副本。你将实现的例子会有一个print queue但可以在3个不同的打印机上打印文件。 阅读全文

线程同步工具(一)控制并发访问资源

声明:本文是《 Java 7 Concurrency Cookbook 》的第三章, 作者: Javier Fernández González 译者:郑玉婷    

控制并发访问资源

这个指南,你将学习怎样使用Java语言提供的Semaphore机制。Semaphore是一个控制访问多个共享资源的计数器。

Semaphore的内容是由Edsger Dijkstra引入并在 THEOS操作系统上第一次使用。

当一个线程想要访问某个共享资源,首先,它必须获得semaphore。如果semaphore的内部计数器的值大于0,那么semaphore减少计数器的值并允许访问共享的资源。计数器的值大于0表示,有可以自由使用的资源,所以线程可以访问并使用它们。

另一种情况,如果semaphore的计数器的值等于0,那么semaphore让线程进入休眠状态一直到计数器大于0。计数器的值等于0表示全部的共享资源都正被线程们使用,所以此线程想要访问就必须等到某个资源成为自由的。

当线程使用完共享资源时,他必须放出semaphore为了让其他线程可以访问共享资源。这个操作会增加semaphore的内部计数器的值。 阅读全文

Java 7 并发编程指南中文版

java 7 concurrency book

原文链接 作者: Javier Fernández González  译者:郑玉婷,许巧辉 校对:方腾飞,欧振聪  

申明:本书由并发编程网组织翻译,只供研究和学习之用,禁止任何人用于商业用途。

当你用计算机工作的时候,你在同时做多样事情。你可以边听音乐边写文档边读取邮件。可以这样做的原因是你的操作系统运行并发任务。并发编程是关于基础与进程的一个提供了多任务或者多程序同时运行还相互沟通来交换数据和相互同步的平台。Java是一个并发平台,在Java程序中提供了很多执行并发任务的类。每个版本,Java提升了促进程序员开发并发程序的功能。这本书包含了在Java版本7的并发API中最重要和最有用的技巧,你可以直接在你的应用程序中使用的。

目录

前言

第一章: 线程管理

  1. 介绍 
  2. 线程的创建和运行 
  3. 获取和设置线程信息 
  4. 线程的中断 
  5. 操作线程的中断机制 
  6. 线程的睡眠和恢复 
  7. 等待线程的终结 
  8. 守护线程的创建和运行 
  9. 处理线程的不受控制异常 
  10. 使用本地线程变量
  11. 线程组
  12. 处理线程组内的不受控制异常
  13. 用线程工厂创建线程

阅读全文

并行快速排序

感谢网友浅水清流投递本稿。

并发算法是多核时代开始流行的技术趋势,比如tbbppl都提供了大量有用的并发算法。

经典算法中,排序是一个很适合采用分治法并发的场合,比如快速排序

常规的快速排序,先在数组中选取一个基准点,将数组分区为小于基准点和大于基准点(相同的数可以到任一边),对分区的子数组递归的执行分区的操作,当子数组长度为1时退出递归。此时数组就完成了排序过程。 阅读全文

参加阿里巴巴校招面试经历

阿里巴巴
本文主要是讲述我参加阿里巴巴2013年校招的经历,感谢并发编程网博主的推荐。

电面

说是电话面试,其实和正常面试感觉没啥区别,也是聊,也是写代码。 用的是这个工具,http://codassium.com/ ,双方写东西,对方都能看到。面试最开始普遍都是让自我介绍,这是吹牛的良好机会,主要内容为:看了哪些牛逼的书,认识哪些牛逼的人,做了哪些牛逼的事。然后就到了问问题的阶段。

问题1.主要是根据做所项目,由于之前做了一个操作系统的模型,所以问了一下进程间调度和通信是如何实现的。又问了一下linux下进程间通信都有哪些方式。

回答大概说调度是基于进程控制块(PCB),我简单做了一个时间片轮转的调度。通信也做的很简单。进程间通信的方式大概是管道(命名、匿名),消息队列,信号,共享内存和socket,只说了这几个。

定制并发类(九)实现一个自定义的Lock类

声明:本文是《 Java 7 Concurrency Cookbook 》的第七章,作者: Javier Fernández González     译者:许巧辉

实现一个自定义的Lock类

锁是Java并发API提供的基本同步机制之一。它允许程序员保护代码的临界区,所以,在某个时刻只有一个线程能执行这个代码块。它提供以下两种操作:

  • lock():当你想要访问一个临界区时,调用这个方法。如果有其他线程正在运行这个临界区,其他线程将阻塞,直到它们被这个锁唤醒,从而获取这个临界区的访问。
  • unlock():你在临界区的尾部调用这个方法,允许其他线程访问这个临界区。

在Java并发API中,锁是在Lock接口及其一些实现类中声明的,比如ReentrantLock类。

在这个指南中,你将学习如何实现你自己的Lock对象,它将实现一个实现了Lock接口并可用来保护临界区的类。

阅读全文

定制并发类(十)实现一个基于优先级的传输队列

声明:本文是《 Java 7 Concurrency Cookbook 》的第七章, 作者: Javier Fernández González 译者:郑玉婷

实现一个基于优先级的传输队列

Java 7 API 提供几种与并发应用相关的数据类型。从这里面,我们想来重点介绍以下2种数据类型:

  • LinkedTransferQueue:这个数据类型支持那些有生产者和消费者结构的程序。 在那些应用,你有一个或者多个数据生产者,一个或多个数据消费者和一个被生产者和消费者共享的数据类型。生产者把数据放入数据结构内,然后消费者从数据结构内提取数据。如果数据结构为空,消费者会被阻塞直到有数据可以消费。如果数据结构满了,生产者就会被阻塞直到有空位来放数据。
  • PriorityBlockingQueue:在这个数据结构,元素是按照顺序储存的。元素们必须实现 带有 compareTo() 方法的 Comparable 接口。当你在结构中插入数据时,它会与数据元素对比直到找到它的位置。

LinkedTransferQueue 的元素是按照抵达顺序储存的,所以越早到的越先被消耗。你有可能需要开发 producer/ consumer 程序,它的消耗顺序是由优先级决定的而不是抵达时间。在这个指南,你将学习如何实现在 producer/ consumer 问题中使用的数据结构,这些元素将被按照他们的优先级排序,级别高的会先被消耗。 阅读全文

定制并发类(六)自定义在计划的线程池内运行的任务

声明:本文是《 Java 7 Concurrency Cookbook 》的第七章, 作者: Javier Fernández González 译者:郑玉婷

自定义在计划的线程池内运行的任务

计划的线程池是 Executor 框架的基本线程池的扩展,允许你定制一个计划来执行一段时间后需要被执行的任务。 它通过 ScheduledThreadPoolExecutor 类来实现,并允许运行以下这两种任务:

  • Delayed 任务:这种任务在一段时间后仅执行一次。
  • Periodic 任务:这种任务在延迟后执行,然后通常周期性运行

Delayed 任务可以执行 Callable 和 Runnable 对象,但是 periodic任务只能执行 Runnable 对象。全部任务通过计划池执行的都必须实现 RunnableScheduledFuture 接口。在这个指南,你将学习如何实现你自己的 RunnableScheduledFuture 接口来执行延迟和周期性任务。 阅读全文

定制并发类(八)自定义在 Fork/Join 框架中运行的任务

声明:本文是《 Java 7 Concurrency Cookbook 》的第七章, 作者: Javier Fernández González 译者:郑玉婷

自定义在 Fork/Join 框架中运行的任务

执行者框架分开了任务的创建和运行。这样,你只要实现 Runnable 对象来使用 Executor 对象。你可以发送 Runnable 任务给执行者,然后它会创建,管理,并终结必要的线程来执行这些任务。

Java 7 在 Fork/Join 框架中提供了特殊的执行者。这个框架是设计用来解决那些可以使用 divide 和 conquer 技术分成更小点的任务的问题。在一个任务内,你要检查你要解决的问题的大小,如果它比设定的大小还大,你就把问题分成2个或多个任务,再使用框架来执行这些任务。

如果问题的大小比设定的大小要小,你可以在任务中直接解决问题,可选择返回结果。Fork/Join 框架实现 work-stealing 算法来提高这类问题的整体表现。
阅读全文

定制并发类(七)实现ThreadFactory接口生成自定义的线程给Fork/Join框架

声明:本文是《 Java 7 Concurrency Cookbook 》的第七章,作者: Javier Fernández González     译者:许巧辉

实现ThreadFactory接口生成自定义的线程给Fork/Join框架

Fork/Join框架是Java7中最有趣的特征之一。它是Executor和ExecutorService接口的一个实现,允许你执行Callable和Runnable任务而不用管理这些执行线程。

这个执行者面向执行能被拆分成更小部分的任务。主要组件如下:

  • 一个特殊任务,实现ForkJoinTask类
  • 两种操作,将任务划分成子任务的fork操作和等待这些子任务结束的join操作
  • 一个算法,优化池中线程的使用的work-stealing算法。当一个任务正在等待它的子任务(结束)时,它的执行线程将执行其他任务(等待执行的任务)。

ForkJoinPool类是Fork/Join的主要类。在它的内部实现,有如下两种元素:

  • 一个存储等待执行任务的列队。
  • 一个执行任务的线程池

在这个指南中,你将学习如何实现一个在ForkJoinPool类中使用的自定义的工作者线程,及如何使用一个工厂来使用它。
阅读全文

定制并发类(五)在一个Executor对象中使用我们的ThreadFactory

声明:本文是《 Java 7 Concurrency Cookbook 》的第七章,作者: Javier Fernández González     译者:许巧辉

在一个Executor对象中使用我们的ThreadFactory

在前面的指南中,实现ThreadFactory接口生成自定义线程,我们引进了工厂模式和提供如何实现一个实现ThreadFactory接口的线程的工厂例子。

执行者框架(Executor framework)是一种机制,它允许你将线程的创建与执行分离。它是基于Executor、ExecutorService接口和实现这两个接口的ThreadPoolExecutor类。它有一个内部的线程池和提供一些方法,这些方法允许你提交两种任务给线程池执行。这两种任务是:

  • 实现Runnable接口的类,用来实现没有返回结果的任务
  • 实现Callable接口的类,用来实现有返回结果的任务

在执行者框架(Executor framework)的内部,它提供一个ThreadFactory接口来创建线程,这是用来产生新的线程。在这个指南中,你将学习如何实现你自己的线程类,用一个工厂来创建这个类的线程,及如何在执行者中使用这个工厂,所以这个执行者将执行你的线程。

阅读全文

定制并发类(四)实现ThreadFactory接口生成自定义的线程

声明:本文是《 Java 7 Concurrency Cookbook 》的第七章,作者: Javier Fernández González     译者:许巧辉

实现ThreadFactory接口生成自定义的线程

在面向对象编程的世界中,工厂模式(factory pattern)是一个被广泛使用的设计模式。它是一个创建模式,它的目的是开发一个类,这个类的使命是创建一个或多个类的对象。然后,当我们要创建一个类的一个对象时,我们使用这个工厂而不是使用new操作。

  • 使用这个工厂,我们集中对象的创建,获取容易改变创建对象的类的优势,或我们创建这些对象的方式,容易限制创建对象的有限资源。比如,我们只能有一个类型的N个对象,就很容易产生关于对象创建的统计数据。

Java提供ThreadFactory接口,用来实现一个Thread对象工厂。Java并发API的一些高级工具,如执行者框架(Executor framework)或Fork/Join框架(Fork/Join framework),使用线程工厂创建线程。

在Java并发API中的其他工厂模式的例子是Executors类。它提供许多方法来创建不同类型的Executor对象。

在这个指南中,你将继承Thread类,以添加新功能,并且你将实现一个线程工厂来创建这个新类的线程。

阅读全文

return top