- 浏览: 467119 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
ty1972873004:
sunwang810812 写道我运行了这个例子,怎么结果是这 ...
Java并发编程: 使用Semaphore限制资源并发访问的线程数 -
lgh1992314:
simpleDean 写道请问,Logger.setLevel ...
Java内置Logger详解 -
sunwang810812:
我运行了这个例子,怎么结果是这样的:2号车泊车6号车泊车5号车 ...
Java并发编程: 使用Semaphore限制资源并发访问的线程数 -
jp260715007:
nanjiwubing123 写道参考你的用法,用如下方式实现 ...
面试题--三个线程循环打印ABC10次的几种解决方法 -
cb_0312:
SurnameDictionary文章我没看完,现在懂了
中文排序
本文将简单介绍用于线程协作的Condition, 并给出一个例子,实现一个多线程题目--有三个线程分别打印A、B、C,请用多线程编程实现,在屏幕上循环打印10次ABCABC…
。
Condition是从JDK 1.5开始有的。API是这么描述的:
以上是Condition接口定义的方法,await()对应于Object#wait(),signal()对应于Object#notify(),signalAll()对应于Object#notifyAll()。
Condition是与Lock结合使用的,通过Lock.newCondition()方法能够创建与Lock绑定的Condition实例。
Lock和Condition的关系就如同 Object.wait(),Object.notify()方法和synchronized一样,它们都可以配合使用完成对多线程协作的控制。
JDK提供的ArrayBlockingQueue很好地诠释了Condition的使用。
public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable { /** Condition for waiting takes */ private final Condition notEmpty; /** Condition for waiting puts */ private final Condition notFull; /** * Inserts element at current put position, advances, and signals. * Call only when holding lock. */ private void insert(E x) { items[putIndex] = x; putIndex = inc(putIndex); ++count; notEmpty.signal(); } /** * Extracts element at current take position, advances, and signals. * Call only when holding lock. */ private E extract() { final Object[] items = this.items; E x = this.<E>cast(items[takeIndex]); items[takeIndex] = null; takeIndex = inc(takeIndex); --count; notFull.signal(); return x; } /** * Deletes item at position i. * Utility for remove and iterator.remove. * Call only when holding lock. */ void removeAt(int i) { final Object[] items = this.items; // if removing front item, just advance if (i == takeIndex) { items[takeIndex] = null; takeIndex = inc(takeIndex); } else { // slide over all others up through putIndex. for (;;) { int nexti = inc(i); if (nexti != putIndex) { items[i] = items[nexti]; i = nexti; } else { items[i] = null; putIndex = i; break; } } } --count; notFull.signal(); } /** * Inserts the specified element at the tail of this queue, waiting * for space to become available if the queue is full. * * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public void put(E e) throws InterruptedException { checkNotNull(e); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == items.length) notFull.await(); insert(e); } finally { lock.unlock(); } } public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == 0) notEmpty.await(); return extract(); } finally { lock.unlock(); } } ... ... }
下面就使用Condition来完成一个线程面试题:有三个线程分别打印A、B、C,请用多线程编程实现,在屏幕上循环打印10次ABCABC…
程序如下:
package my.thread.test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; /** * 题目:有三个线程分别打印A、B、C,请用多线程编程实现,在屏幕上循环打印10次ABCABC… * * 本程序采用Lock和Condition来实现。 * * @author Eric * */ public class ConditionExample { private Lock lock = new ReentrantLock(); private Condition conditionA = lock.newCondition(); private Condition conditionB = lock.newCondition(); private Condition conditionC = lock.newCondition(); /** 当前线程的名字 */ private char currentThreadName = 'A'; private static final Logger logger = Logger .getLogger("my.thread.test.OrderPrintTest"); public static void main(String[] args) { ConditionExample ce = new ConditionExample(); ExecutorService service = Executors.newFixedThreadPool(3); service.execute(ce.new ThreadA()); service.execute(ce.new ThreadB()); service.execute(ce.new ThreadC()); service.shutdown(); } private class ThreadA implements Runnable { public void run() { for (int i = 0; i < 10; i++) { lock.lock(); try { while (currentThreadName != 'A') { try { /* * 如果当前线程名字不是A,那么ThreadA就处理等待状态 */ conditionA.await(); } catch (InterruptedException e) { logger.severe(e.getLocalizedMessage()); } } /* * 打印出第几遍以及A信息 */ System.out.println(String.format("第%d遍", i + 1)); System.out.println("A"); /* * 将当前线程名置为B, 然后通知ThreadB执行 */ currentThreadName = 'B'; conditionB.signal(); } finally { lock.unlock(); } } } } private class ThreadB implements Runnable { public void run() { for (int i = 0; i < 10; i++) { lock.lock(); try { while (currentThreadName != 'B') { try { /* * 如果当前线程名字不是B,那么ThreadB就处理等待状态 */ conditionB.await(); } catch (InterruptedException e) { logger.severe(e.getLocalizedMessage()); } } /* * 打印信息B */ System.out.println("B"); /* * 将当前线程值置为C 并通过ThreadC来执行 */ currentThreadName = 'C'; conditionC.signal(); } finally { lock.unlock(); } } } } private class ThreadC implements Runnable { public void run() { for (int i = 0; i < 10; i++) { lock.lock(); try { while (currentThreadName != 'C') { try { /* * 如果当前线程名字不是C,那么ThreadC就处理等待状态 */ conditionC.await(); } catch (InterruptedException e) { logger.severe(e.getLocalizedMessage()); } } /* * 打印信息C */ System.out.println("C"); System.out.println(); /* * 将当前线程值置为A 并通过ThreadA来执行 */ currentThreadName = 'A'; conditionA.signal(); } finally { lock.unlock(); } } } } }
程序运行结果如下:
第1遍
A
B
C
第2遍
A
B
C
第3遍
A
B
C
第4遍
A
B
C
第5遍
A
B
C
第6遍
A
B
C
第7遍
A
B
C
第8遍
A
B
C
第9遍
A
B
C
第10遍
A
B
C
发表评论
-
工厂类中移除if/else语句
2016-07-10 19:52 908面向对象语言的一个强大的特性是多态,它可以用来在代码中移除 ... -
Java编程练手100题
2014-12-11 17:13 6733本文给出100道Java编程练手的程序。 列表如下: 面 ... -
数组复制的三种方法
2014-11-30 12:57 2220本文将给出三种实现数组复制的方法 (以复制整数数组为例)。 ... -
数组复制的三种方法
2014-11-30 12:54 0本文将给出三种实现数组复制的方法 (以复制整数数组为例)。 ... -
四种复制文件的方法
2014-11-29 13:21 1744尽管Java提供了一个类ava.io.File用于文件的操 ... -
判断一个字符串中的字符是否都只出现一次
2014-11-25 12:58 2733本篇博文将给大家带来几个判断一个字符串中的字符是否都只出现一 ... -
使用正则表达式判断一个数是否为素数
2014-11-23 13:35 2173正则表达式能够用于判断一个数是否为素数,这个以前完全没有想过 ... -
几个可以用英文单词表达的正则表达式
2014-11-21 13:12 3758本文,我们将来看一下几个可以用英文单词表达的正则表达式。这些 ... -
(广度优先搜索)打印所有可能的括号组合
2014-11-20 11:58 1960问题:给定一个正整n,作为括号的对数,输出所有括号可能 ... -
随机产生由特殊字符,大小写字母以及数字组成的字符串,且每种字符都至少出现一次
2014-11-19 14:48 3984题目:随机产生字符串,字符串中的字符只能由特殊字符 (! ... -
找出1到n缺失的一个数
2014-11-18 12:57 3182题目:Problem description: You h ... -
EnumSet的几个例子
2014-11-14 16:24 8757EnumSet 是一个与枚举类型一起使用的专用 Set 实现 ... -
给定两个有序数组和一个指定的sum值,从两个数组中各找一个数使得这两个数的和与指定的sum值相差最小
2014-11-12 11:24 3334题目:给定两个有序数组和一个指定的sum值,从两个数组 ... -
Java面试编程题练手
2014-11-04 22:49 6706面试编程 写一个程序,去除有序数组中的重复数字 编 ... -
Collections用法整理
2014-10-22 20:55 9851Collections (java.util.Collect ... -
The Code Sample 代码实例 个人博客开通
2014-09-04 18:48 1423个人博客小站开通 http://thecodesample. ... -
Collections.emptyXXX方法
2014-06-08 13:37 2147从JDK 1.5开始, Collections集合工具类中预先 ... -
这代码怎么就打印出"hello world"了呢?
2014-06-08 00:37 7400for (long l = 4946144450195624L ... -
最短时间过桥
2014-04-21 22:03 4158本文用代码实现最短时间过桥,并且打印如下两个例子的最小过桥时间 ... -
将数组分割成差值最小的子集
2014-04-20 22:34 2906本文使用位掩码实现一个功能 ==》将数组分割成差值最小的子集 ...
相关推荐
【Java并发编程--BlockingQueue详解】 BlockingQueue 是 Java 并发包(java.util.concurrent)中的一个接口,它扩展了 Queue 接口,并引入了线程安全的特性,特别适合于多线程环境下的数据共享。 BlockingQueue 的...
书中可能包含了大量示例代码,通过实例解析Java并发编程中的常见问题,如死锁、活锁、饥饿现象,以及如何避免这些问题。此外,还可能涉及了Java内存模型(JMM)的理解,以及如何使用Lock接口和Condition来实现更细...
本资料“Java并发编程设计原则和模式”深入探讨了如何在Java环境中有效地进行并发处理,以充分利用系统资源并避免潜在的并发问题。 一、并发编程基础 并发是指两个或多个操作在同一时间段内执行,但并不意味着这些...
总的来说,《Java并发编程实战》这本书不仅提供了丰富的理论知识,还通过大量的实例源码帮助读者将理论付诸实践,是Java开发者提升并发编程技能的必备参考。通过学习书中的内容,开发者能够更好地理解和掌握Java并发...
1. **jcip-examples-src.jar**:这个JAR文件包含《Java并发编程实践》一书中的所有源代码实例,它是学习并发编程的重要资源。通过阅读和分析这些代码,我们可以深入理解Java并发API的用法,如`java.util.concurrent`...
1. **并发基础**:介绍Java并发编程的基本概念,包括线程、进程、同步与互斥、死锁等。读者将了解Java中Thread类和Runnable接口的使用,以及如何创建和管理线程。 2. **线程安全**:讨论线程不安全的代码示例,以及...
本章节深入探讨了Java并发编程中显示锁的使用及其高级特性,特别是`ReentrantLock`。通过对`Lock`接口的学习,我们不仅掌握了如何更灵活地控制锁的获取和释放,还学会了如何利用`Condition`实现更精细的线程同步策略...
《Java并发编程实战》这本书是Java并发编程领域的一本经典之作,它深入浅出地讲解了如何在Java环境中高效、安全地进行多线程编程。源码整理集合`concurrent-programming-master`提供了书中示例代码,对于学习和理解...
在Java并发编程中,`Lock`接口和`ReentrantLock`类扮演着至关重要的角色。它们为多线程环境提供了更高级别的控制和灵活性,弥补了内置锁(也称为监视器锁或内部锁)的不足。`ReentrantLock`是Java 5.0引入的,作为对...
Java并发编程是软件开发中的一个核心领域,尤其是在服务器端应用和多核处理器系统中,它的重要性日益凸显。这个“Java并发编程ppt”压缩包文件很可能包含了一套详细的讲解材料,帮助学习者理解并掌握Java环境下的多...
总之,Java并发编程是一门深奥的学问,它涵盖了线程创建与管理、同步与通信、并发工具的使用等多个方面。通过学习和实践,你可以构建出更加健壮、高效的并发应用程序。对于"java并发编程实战"的学习,不仅要理解理论...
Java并发编程实战 本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及...
Java并发编程是开发高效应用程序的关键领域,特别是在多核处理器系统中。并发编程涉及的主要目标是确保线程安全、解决活跃性问题以及优化性能。 **1. 线程的三大性质** - **可见性**:当一个线程修改了共享变量,...
- Condition接口:与Lock配合使用,提供更细粒度的线程间通信。 6. **线程优先级** - Java线程有10个优先级,默认是Thread.NORM_PRIORITY(5)。但优先级并不保证执行顺序,只是影响调度概率。 7. **守护线程...
《Java2.0网络多线程编程实例教程》是一本由李荣贵等人编写的书籍,专注于Java2.0(即Java SE 2)平台下的网络编程和多线程技术。该书通过丰富的实例,旨在帮助读者深入理解和掌握这两项核心的Java开发技能。 在...
在商业编程中,这经常用于构建复杂的、高并发的应用,如服务器端程序、实时交易系统或大型游戏引擎等。 首先,理解线程的创建和管理。在大多数编程语言中,都有内置的库或者框架支持线程操作。例如,在Java中,我们...
Java并发编程中的ReentrantLock是Java并发包(java.util.concurrent,简称JUC)中的一个重要的锁机制,它是Lock接口的一个具体实现,提供了比synchronized更强大的锁定功能和更细粒度的控制。ReentrantLock的主要...