- 浏览: 140504 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
randyjiawenjie1:
终于遇到一个人讲清楚了
阻塞I/O,非阻塞I/O -
dxqrr:
学习了。。。。
java中堆和堆栈的区别 -
tanhong:
[color=yellow][/color] ...
“is a”和“has a”的区别 -
uuid198909:
代码看着是比较………………
JDK5新特性--java.util.concurrent Semaphore(8) -
heipark:
兄弟,咱这代码纠结了点....
JDK5新特性--java.util.concurrent Semaphore(8)
Lock 接口
ReentrantLock 是 Lock 的具体类, Lock 提供了以下一些方法:
- lock(): 请求锁定,如果锁已被别的线程锁定,调用此方法的线程被阻断进入等待状态。
- tryLock() :如果锁没被别的线程锁定,进入锁定状态,并返回 true 。若锁已被锁定,返回 false ,不进入等待状态。此方法还可带时间参数,如果锁在方法执行时已被锁定,线程将继续等待规定的时间,若还不行才返回 false 。
- unlock() :取消锁定,需要注意的是 Lock 不会自动取消,编程时必须手动解锁。
代码:
// 生成一个锁 Lock lock = new ReentrantLock(); public void accessProtectedResource() { lock.lock(); // 取得锁定 try { // 对共享资源进行操作 } finally { // 一定记着把锁取消掉,锁本身是不会自动解锁的 lock.unlock(); } } |
ReadWriteLock 接口
为了提高效率有些共享资源允许同时进行多个读的操作,但只允许一个写的操作,比如一个文件,只要其内容不变可以让多个线程同时读,不必做排他的锁定,排他的锁定只有在写的时候需要,以保证别的线程不会看到数据不完整的文件。 ReadWriteLock 可满足这种需要。 ReadWriteLock 内置两个 Lock ,一个是读的 Lock ,一个是写的 Lock 。多个线程可同时得到读的 Lock ,但只有一个线程能得到写的 Lock ,而且写的 Lock 被锁定后,任何线程都不能得到 Lock 。 ReadWriteLock 提供的方法有:
- readLock(): 返回一个读的 lock
- writeLock(): 返回一个写的 lock, 此 lock 是排他的。
ReadWriteLock 的例子:
public class FileOperator{ // 初始化一个 ReadWriteLock ReadWriteLock lock = new ReentrantReadWriteLock(); public String read() { // 得到 readLock 并锁定 Lock readLock = lock.readLock(); readLock.lock(); try { // 做读的工作 return "Read something"; } finally { readLock.unlock(); } }
public void write(String content) { // 得到 writeLock 并锁定 Lock writeLock = lock.writeLock(); writeLock.lock(); try { // 做读的工作 } finally { writeLock.unlock(); } } } |
需要注意的是 ReadWriteLock 提供了一个高效的锁定机理,但最终程序的运行效率是和程序的设计息息相关的,比如说如果读的线程和写的线程同时在等待,要考虑是先发放读的 lock 还是先发放写的 lock 。如果写发生的频率不高,而且快,可以考虑先给写的 lock 。还要考虑的问题是如果一个写正在等待读完成,此时一个新的读进来,是否要给这个新的读发锁,如果发了,可能导致写的线程等很久。等等此类问题在编程时都要给予充分的考虑。
Condition 接口:
有时候线程取得 lock 后需要在一定条件下才能做某些工作,比如说经典的 Producer 和 Consumer 问题, Consumer 必须在篮子里有苹果的时候才能吃苹果,否则它必须暂时放弃对篮子的锁定,等到 Producer 往篮子里放了苹果后再去拿来吃。而 Producer 必须等到篮子空了才能往里放苹果,否则它也需要暂时解锁等 Consumer 把苹果吃了才能往篮子里放苹果。在 Java 5.0 以前,这种功能是由 Object 类的 wait(), notify() 和 notifyAll() 等方法实现的,在 5.0 里面,这些功能集中到了 Condition 这个接口来实现, Condition 提供以下方法:
- await() :使调用此方法的线程放弃锁定,进入睡眠直到被打断或被唤醒。
- signal(): 唤醒一个等待的线程
- signalAll() :唤醒所有等待的线程
Condition 的例子:
public class Basket { Lock lock = new ReentrantLock(); // 产生 Condition 对象 Condition produced = lock.newCondition(); Condition consumed = lock.newCondition(); boolean available = false;
public void produce() throws InterruptedException { lock.lock(); try { if(available){ consumed.await(); // 放弃 lock 进入睡眠 } /* 生产苹果 */ System.out.println("Apple produced."); available = true; produced.signal(); // 发信号唤醒等待这个 Condition 的线程 } finally { lock.unlock(); } }
public void consume() throws InterruptedException { lock.lock(); try { if(!available){ produced.await();// 放弃 lock 进入睡眠 } /* 吃苹果 */ System.out.println("Apple consumed."); available = false; consumed.signal();// 发信号唤醒等待这个 Condition 的线程 } finally { lock.unlock(); } } } |
ConditionTester:
public class ConditionTester {
public static void main(String[] args) throws InterruptedException{ final Basket basket = new Basket(); // 定义一个 producer Runnable producer = new Runnable() { public void run() { try { basket.produce(); } catch (InterruptedException ex) { ex.printStackTrace(); } } }; // 定义一个 consumer Runnable consumer = new Runnable() { public void run() { try { basket.consume(); } catch (InterruptedException ex) { ex.printStackTrace(); } } }; // 各产生 10 个 consumer 和 producer ExecutorService service = Executors.newCachedThreadPool(); for(int i=0; i < 10; i++) service.submit(consumer); Thread.sleep(2000); for(int i=0; i<10; i++) service.submit(producer); service.shutdown(); } } |
5: Synchronizer:同步装置
Java 5.0 里新加了 4 个协调线程间进程的同步装置,它们分别是 Semaphore, CountDownLatch, CyclicBarrier 和 Exchanger.
Semaphore:
用来管理一个资源池的工具, Semaphore 可以看成是个通行证,线程要想从资源池拿到资源必须先拿到通行证, Semaphore 提供的通行证数量和资源池的大小一致。如果线程暂时拿不到通行证,线程就会被阻断进入等待状态。以下是一个例子:
public class Pool { ArrayList pool = null; Semaphore pass = null; public Pool(int size){ // 初始化资源池 pool = new ArrayList(); for(int i=0; i pool.add("Resource "+i); } //Semaphore 的大小和资源池的大小一致 pass = new Semaphore(size); } public String get() throws InterruptedException{ // 获取通行证 , 只有得到通行证后才能得到资源 pass.acquire(); return getResource(); } public void put(String resource){ // 归还通行证,并归还资源 pass.release(); releaseResource(resource); } private synchronized String getResource() { String result = pool.get(0); pool.remove(0); System.out.println("Give out "+result); return result; } private synchronized void releaseResource(String resource) { System.out.println("return "+resource); pool.add(resource); } } |
SemaphoreTest:
public class SemaphoreTest { public static void main(String[] args){ final Pool aPool = new Pool(2); Runnable worker = new Runnable() { public void run() { String resource = null; try { // 取得 resource resource = aPool.get(); } catch (InterruptedException ex) { ex.printStackTrace(); } // 用 resource 做工作 System.out.println("I worked on "+resource); // 归还 resource aPool.put(resource); } }; ExecutorService service = Executors.newCachedThreadPool(); for(int i=0; i<20; i++){ service.submit(worker); } service.shutdown(); } } |
发表评论
-
JDK5新特性--java.util.concurrent ExecutorCompletionSe
2008-07-04 10:25 1261考 虑以下场景:浏览网页时,浏览器了5个线程下载网页中的图片 ... -
JDK5新特性--java.util.concurrent CyclicBarrier(3)
2008-07-03 15:13 1137在 实际应用中,有时候需要多个线程同时工作以完成同一件事情,而 ... -
java基础--Java 5.0多线程编程(2)
2008-07-03 14:30 2537*1: 定义了几个任务 *2: 初始了任务执行工具。 ... -
java基础--Java 5.0多线程编程(1)
2008-07-03 14:13 1466Java自 1995 ... -
关于用信号量Semaphore完成互斥锁Mutex
2008-07-03 11:26 2589本文探讨用信号量Semaphore实现互斥锁Mutex的问题 ... -
JDK5新特性--java.util.concurrent Semaphore(8)
2008-07-03 10:43 5864操作系统的信号量是个很重要的概念,在进程控制方面都有应用。Ja ... -
使用Callable返回结果
2008-07-02 14:50 1720本文是Sun ... -
Java线程join()方法的用处
2008-07-02 14:24 6144run() 和start() 是大家都很熟悉的两个方法。把希望 ... -
JDK5新特性--java.util.concurrent BlockingQueue(4)
2008-07-02 10:57 2446并 发库中的BlockingQueue 是一个比较好玩的类,顾 ... -
JDK5新特性--java.util.concurrent CountDownLatch(5)
2008-07-02 09:34 1381从 名字可以看出,CountDownLatch 是一个倒数计 ... -
中断JAVA线程
2008-06-30 22:44 1517在JAVA中,通过其对线程类的内嵌支持,编程人员编 ... -
JAVA中断线程的方法
2008-06-30 11:26 2118Thread.stop , Thread.suspend , ... -
不可变性
2008-05-28 09:29 9833.4 不可变性 为了满足同步的需要,另一种方法是使用不可变 ... -
使用不常进行修改的可变集合来减少应用程序的同步开销
2008-05-28 00:12 1304使用多个 Java 线程之间 ... -
正确理解java构造函数内非final函数
2008-05-27 21:49 1418大家都知道java构造 的使用方法吧, 可能大家都用它来进行 ... -
Java 理论和实践:变还是不变?
2008-05-27 21:28 860不变对象具备许多能更方便地使用他们的特性,包括不严格的同步需求 ... -
线程同步原则
2008-05-27 21:14 995同步的基本规则:只要读取可能由其他线程写入的变量,或者写入随后 ... -
Java的多线程及安全性
2008-05-27 21:11 3027多线程 是一种机制, ... -
利于ThreadLocal管理Hibernate Session
2008-05-26 16:25 1125在利用Hibernate开发DAO模块时,我们和 ... -
ThreadLocal的几种误区
2008-05-26 16:10 937ThreadLocal的几种误区 最近由于需要用到 ...
相关推荐
最新Java 5.0多线程编程。
Java5.0多线程编程实践.pdf
java Java多线程 多线程 java Java多线程 多线程 java Java多线程 多线程
javathread.zip 10.Java多线程编程(线程池、生产者消费者、存取款实例) javautil.zip 11.Java常用实体类 javaxml.zip 14.XML属性文件 第4部分(6个程序包) javagui.zip 15.Java GUI库对比实例 javaawt.zip ...
javathread.zip 10.Java多线程编程(线程池、生产者消费者、存取款实例) javautil.zip 11.Java常用实体类 javaxml.zip 14.XML属性文件 第4部分(6个程序包) javagui.zip 15.Java GUI库对比实例 javaawt.zip 16....
1.7 Java 5.0多线程编程 1.8 Java Socket编程 1.9 Java的内存泄漏 1.10 抽象类与接口的区别 1.11 Java变量类型间的相互转换 2 JAVA与WEB 2.1 JMX规范 2.1.1 JMX概述 2.1.2 设备层(Instrumentation Level) 2.1.3 ...
Java自1995年面世以来得到了广泛得一个运用,但是对多...在Java 5.0之前Java里的多线程编程主要是通过Thread类,Runnable接口,Object对象中的wait()、 notify()、 notifyAll()等方法和synchronized关键词来实现的。
《精通Java:JDK、数据库系统开发Web开发》全书共分27章,内容涵盖了Java编程环境概述、基础语法、面向对象软件设计方法、线程、数据集合、网络编程、图形编程、多媒体编程以及Java Web开发。本书每一节的例子都是...
1. 前言 1-4 1.1. JAVA特点 1-4 1.2. 运行原理 1-4 1.3. JAVA目录 1-4 2. 一•基础知识 2-4 2.1. 配置环境 2-4 2.2. Java中基本概念 2...17.9. JAVA5.0 的注释 (Annotation) 17-73 17.10. Callable 和 Future接口 17-74
Java精华学习资料 深入JAVA API 深入理解嵌套类和内部类 文件和流 java中的一些常用词汇 ...Java 5.0多线程编程 Java Socket编程 Java的内存泄漏 抽象类与接口的区别 Java变量类型间的相互转换 ……
包括:多线程、集合框架、网络API、数据库编程、分布式对象等,深入探究了Swing、Java 2D API、Javaean、Java安全模式、XML、注释、元数据等主题,同量涉及本地方法、国际化以及JDK 5.0的内容。本书适合软件开发人员...
javathread.zip 10.Java多线程编程(线程池、生产者消费者、存取款实例) javautil.zip 11.Java常用实体类 javaxml.zip 14.XML属性文件 第4部分(6个程序包) javagui.zip 15.Java GUI库对比实例 javaawt.zip ...
第12章 java多线程技术与应用性能优化 12.1 java多线程技术 12.1.1 进程与线程 12.1.2 线程的生命周期 12.2 并行任务与性能 12.2.1 并行任务与多线程 12.2.2 并行任务与死锁 12.3 线程池技术与应用性能优化 12.3.1 ...
共有19个章节,169个实例,内容涉及Java的语言基础、面向对象程序设计、数字处理、数组与集合、字符串、异常处理、文件操作、多线程、Swing编程、图形和多媒体编程、反射机制、网络程序设计、数据库编程、Applet、...
包括:多线程、集合框架、网络API、数据库编程、分布式对象等,深入探究了Swing、Java 2D API、Javaean、Java安全模式、XML、注释、元数据等主题,同量涉及本地方法、国际化以及JDK 5.0的内容。本书适合软件开发人员...