- 浏览: 143842 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
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 1294考 虑以下场景:浏览网页时,浏览器了5个线程下载网页中的图片 ... -
JDK5新特性--java.util.concurrent CyclicBarrier(3)
2008-07-03 15:13 1176在 实际应用中,有时候需要多个线程同时工作以完成同一件事情,而 ... -
java基础--Java 5.0多线程编程(2)
2008-07-03 14:30 2580*1: 定义了几个任务 *2: 初始了任务执行工具。 ... -
java基础--Java 5.0多线程编程(1)
2008-07-03 14:13 1501Java自 1995 ... -
关于用信号量Semaphore完成互斥锁Mutex
2008-07-03 11:26 2632本文探讨用信号量Semaphore实现互斥锁Mutex的问题 ... -
JDK5新特性--java.util.concurrent Semaphore(8)
2008-07-03 10:43 5911操作系统的信号量是个很重要的概念,在进程控制方面都有应用。Ja ... -
使用Callable返回结果
2008-07-02 14:50 1759本文是Sun ... -
Java线程join()方法的用处
2008-07-02 14:24 6210run() 和start() 是大家都很熟悉的两个方法。把希望 ... -
JDK5新特性--java.util.concurrent BlockingQueue(4)
2008-07-02 10:57 2479并 发库中的BlockingQueue 是一个比较好玩的类,顾 ... -
JDK5新特性--java.util.concurrent CountDownLatch(5)
2008-07-02 09:34 1409从 名字可以看出,CountDownLatch 是一个倒数计 ... -
中断JAVA线程
2008-06-30 22:44 1549在JAVA中,通过其对线程类的内嵌支持,编程人员编 ... -
JAVA中断线程的方法
2008-06-30 11:26 2158Thread.stop , Thread.suspend , ... -
不可变性
2008-05-28 09:29 10263.4 不可变性 为了满足同步的需要,另一种方法是使用不可变 ... -
使用不常进行修改的可变集合来减少应用程序的同步开销
2008-05-28 00:12 1328使用多个 Java 线程之间 ... -
正确理解java构造函数内非final函数
2008-05-27 21:49 1450大家都知道java构造 的使用方法吧, 可能大家都用它来进行 ... -
Java 理论和实践:变还是不变?
2008-05-27 21:28 892不变对象具备许多能更方便地使用他们的特性,包括不严格的同步需求 ... -
线程同步原则
2008-05-27 21:14 1031同步的基本规则:只要读取可能由其他线程写入的变量,或者写入随后 ... -
Java的多线程及安全性
2008-05-27 21:11 3062多线程 是一种机制, ... -
利于ThreadLocal管理Hibernate Session
2008-05-26 16:25 1159在利用Hibernate开发DAO模块时,我们和 ... -
ThreadLocal的几种误区
2008-05-26 16:10 971ThreadLocal的几种误区 最近由于需要用到 ...
相关推荐
- **并发工具包**:包括了新的并发类,如`Executor`框架、`ConcurrentHashMap`等,使得编写多线程程序更加容易。 - **泛型集合**:提供了泛型化的集合类,提高了类型安全性。 - **正则表达式引擎**:支持更强大的...
最新Java 5.0多线程编程。
"2009-10-20 accp 5.0 s1java内部测试题3套" 这个标题表明这是一组面向ACCP(北大青鸟计算机职业认证课程)5.0阶段S1级别的Java编程语言的内部测试题目。日期“2009-10-20”可能代表这些试题的发布或更新时间。"s1...
### Java 5.0 多线程编程 #### 核心知识点概述 Java 5.0 的发布标志着 Java 在并发编程领域的一个重大突破。在 Java 5.0 之前,多线程编程主要依赖于 `Thread` 类、`Runnable` 接口以及对象的 `wait()`、`notify()...
Java 5.0版本引入了许多重要的新特性和改进,其中就包括对多线程编程的加强。这一进步在Java并发API中得到了体现,尤其是`java.util.concurrent`包的引入,极大地方便了Java并发程序的开发。本文将结合Java 5.0中的...
通过以上两个新增的线程创建方式,我们可以看到Java 5.0版本在多线程编程方面的改进和增强。使用`Callable`接口和线程池不仅提高了线程管理的灵活性,还增强了程序的可扩展性和性能表现。在实际开发过程中,根据具体...
8. **多线程(Multithreading)**:Java API提供了Thread类和Runnable接口来支持多线程编程,理解和掌握线程的同步、互斥、线程池等概念对于开发高并发应用程序至关重要。 9. **I/O流(Input/Output Streams)**:...
并发处理方面,增加了并发工具类如`ExecutorService`,`Semaphore`和`CountDownLatch`等,使得多线程编程更加容易和高效。 在面向对象设计方面,Java 5.0支持注解(Annotations),这是一种元数据形式,可以用来...
8. **多线程**:Java内置对多线程的支持,通过Thread类或实现Runnable接口来创建和管理线程,理解并发编程的概念,如同步、互斥、死锁和线程池等。 9. **接口与抽象类**:接口是完全抽象的,只包含方法签名,不包含...
**Java的高级编程接口**包括四个专题:Java图形GUI编程、多线程编程、I/O编程和网络编程。 - **Java图形GUI编程**涉及Java的AWT(Abstract Window Toolkit)和Swing库,用于创建用户界面。AWT提供了基本的组件和...
- **多线程**:Java支持多线程编程,可以实现并发操作。 **用途:** - **开发应用程序**(Applications):适用于桌面应用程序、移动应用程序等。 - **开发Applet**:早期用于开发Web页面中的小应用程序或组件。 - ...
Java编程语言以其强大的功能和广泛的应用领域而备受程序员青睐,特别是在多线程、泛型、反射、输入/输出(IO)以及容器类和注解等方面的深入理解和应用,能够提升程序的性能和可维护性。本资源包聚焦于这些关键知识...
例如,使用LRU(Least Recently Used)缓存策略来处理常用日志查询,通过多线程或异步I/O提高并发处理能力,以及利用CPU亲和性调度来减少上下文切换开销。 最后,Roclog v5.0.23.0的源码还提供了学习和研究的机会,...
API则包含了大量的类库,如集合框架、IO流、网络编程、多线程、反射等,这些都是Java程序员日常工作中不可或缺的部分。 在“Java SE核心2”中,可能会涉及以下高级主题: 1. **多线程**:Java对多线程支持非常完善...
7. **多线程**:Java提供了内置支持进行多任务处理,通过Thread类和Runnable接口实现。这部分会讲解线程的创建、同步和通信方法。 8. **文件和文件系统**:学习如何操作文件和目录,包括创建、删除、移动和读写文件...
10. **并发API的扩展**:包括`java.util.concurrent`包,提供了线程池、并发集合、并发工具类等,极大地改善了多线程编程的体验。 这些新特性极大地提升了Java的生产力和可维护性。通过阅读中文版的Java 5.0 API...
10. **并发编程改进**:Java 5.0引入了`java.util.concurrent`包,包含各种线程安全的数据结构和并发工具类,如ExecutorService、Future、CountDownLatch和CyclicBarrier等,简化了多线程编程。 以上只是Java API ...