- 浏览: 140510 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
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)
Java自 1995 年面世以来得到了广泛得一个运用,但是对多线程编程的支持 Java 很长时间一直停留在初级阶段。在 Java 5.0 之前 Java 里的多线程编程主要是通过 Thread 类, Runnable 接口, Object 对象中的 wait() 、 notify() 、 notifyAll() 等方法和 synchronized 关键词来实现的。这些工具虽然能在大多数情况下解决对共享资源的管理和线程间的调度,但存在以下几个问题
1. 过于原始,拿来就能用的功能有限,即使是要实现简单的多线程功能也需要编写大量的代码。这些工具就像汇编语言一样难以学习和使用,比这更糟糕的是稍有不慎它们还可能被错误地使用,而且这样的错误很难被发现。
2. 如果使用不当,会使程序的运行效率大大降低。
3. 为了提高开发效率,简化编程,开发人员在做项目的时候往往需要写一些共享的工具来实现一些普遍适用的功能。但因为没有规范,相同的工具会被重复地开发,造成资源浪费。
4. 因为锁定的功能是通过 Synchronized 来实现的,这是一种块结构,只能对代码中的一段代码进行锁定,而且锁定是单一的。如以下代码所示:
synchronized ( lock ) { // 执行对共享资源的操作 …… } |
一些复杂的功能就很难被实现。比如说如果程序需要取得 lock A 和 lock B 来进行操作 1 ,然后需要取得 lock C 并且释放 lock A 来进行操作 2 , Java 5.0 之前的多线程框架就显得无能为力了。
因为这些问题,程序员对旧的框架一直颇有微词。这种情况一直到 Java 5.0 才有较大的改观,一系列的多线程工具包被纳入了标准库文件。这些工具包括了一个新的多线程程序的执行框架,使编程人员可方便地协调和调度线程的运行,并且新加入了一些高性能的常用的工具,使程序更容易编写,运行效率更高。本文将分类并结合例子来介绍这些新加的多线程工具。
在我们开始介绍 Java 5.0 里的新 Concurrent 工具前让我们先来看一下一个用旧的多线程工具编写的程序,这个程序里有一个 Server 线程,它需要启动两个 Component , Server 线程需等到 Component 线程完毕后再继续。相同的功能在 Synchronizer 一章里用新加的工具 CountDownLatch 有相同的实现。两个程序,孰优孰劣,哪个程序更容易编写,哪个程序更容易理解,相信大家看过之后不难得出结论。
public class ServerThread { Object concLock = new Object(); int count = 2; public void runTwoThreads() { // 启动两个线程去初始化组件 new Thread(new ComponentThread1(this)).start(); new Thread(new ComponentThread1(this)).start(); // Wait for other thread while(count != 0) { synchronized(concLock) { try { concLock.wait(); System.out.println("Wake up."); } catch (InterruptedException ie) { // 处理异常 } } } System.out.println("Server is up."); } public void callBack() { synchronized(concLock) { count--; concLock.notifyAll(); } } public static void main(String[] args){ ServerThread server = new ServerThread(); server.runTwoThreads(); } }
public class ComponentThread1 implements Runnable { private ServerThread server; public ComponentThread1(ServerThread server) { this.server = server; } public void run() { // 做组件初始化的工作 System.out.println("Do component initialization."); server.callBack(); } } |
1:三个新加的多线程包
Java 5.0 里新加入了三个多线程包: java.util.concurrent, java.util.concurrent.atomic, java.util.concurrent.locks.
- java.util.concurrent 包含了常用的多线程工具,是新的多线程工具的主体。
- java.util.concurrent.atomic 包含了不用加锁情况下就能改变值的原子变量,比如说 AtomicInteger 提供了 addAndGet() 方法。 Add 和 Get 是两个不同的操作,为了保证别的线程不干扰,以往的做法是先锁定共享的变量,然后在锁定的范围内进行两步操作。但用 AtomicInteger.addAndGet() 就不用担心锁定的事了,其内部实现保证了这两步操作是在原子量级发生的,不会被别的线程干扰。
- java.util.concurrent.locks 包包含锁定的工具。
2: Callable 和 Future接口
Callable 是类似于 Runnable 的接口,实现 Callable 接口的类和实现 Runnable 的类都是可被其它线程执行的任务。 Callable 和 Runnable 有几点不同:
- Callable 规定的方法是 call() ,而 Runnable 规定的方法是 run().
- Callable 的任务执行后可返回值,而 Runnable 的任务是不能返回值的。
- call ()方法可抛出异常,而 run ()方法是不能抛出异常的。
- 运行 Callable 任务可拿到一个 Future 对象,通过 Future 对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
以下是 Callable 的一个例子:
public class DoCallStuff implements Callable{ // *1 private int aInt; public DoCallStuff(int aInt) { this.aInt = aInt; } public String call() throws Exception { //*2 boolean resultOk = false; if(aInt == 0){ resultOk = true; } else if(aInt == 1){ while(true){ //infinite loop System.out.println("looping...."); Thread.sleep(3000); } } else { throw new Exception("Callable terminated with Exception!"); //*3 } if(resultOk){ return "Task done."; } else { return "Task failed"; } } } |
*1: 名为 DoCallStuff 类实现了 Callable , String 将是 call 方法的返回值类型。例子中用了 String ,但可以是任何 Java 类。
*2: call 方法的返回值类型为 String ,这是和类的定义相对应的。并且可以抛出异常。
*3: call 方法可以抛出异常,如加重的斜体字所示。
以下是调用 DoCallStuff 的主程序。
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class Executor { public static void main(String[] args){ //*1 DoCallStuff call1 = new DoCallStuff(0); DoCallStuff call2 = new DoCallStuff(1); DoCallStuff call3 = new DoCallStuff(2); //*2 ExecutorService es = Executors.newFixedThreadPool(3); //*3 Future future1 = es.submit(call1); Future future2 = es.submit(call2); Future future3 = es.submit(call3); try { //*4 System.out.println(future1.get()); //*5 Thread.sleep(3000); System.out.println("Thread 2 terminated? :" + future2.cancel(true)); //*6 System.out.println(future3.get()); } catch (ExecutionException ex) { ex.printStackTrace(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } |
发表评论
-
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多线程编程(3)
2008-07-03 14:35 1324Lock 接口 ReentrantLock 是 Loc ... -
java基础--Java 5.0多线程编程(2)
2008-07-03 14:30 2537*1: 定义了几个任务 *2: 初始了任务执行工具。 ... -
关于用信号量Semaphore完成互斥锁Mutex
2008-07-03 11:26 2589本文探讨用信号量Semaphore实现互斥锁Mutex的问题 ... -
JDK5新特性--java.util.concurrent Semaphore(8)
2008-07-03 10:43 5866操作系统的信号量是个很重要的概念,在进程控制方面都有应用。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 ...
包括:多线程、集合框架、网络API、数据库编程、分布式对象等,深入探究了Swing、Java 2D API、Javaean、Java安全模式、XML、注释、元数据等主题,同量涉及本地方法、国际化以及JDK 5.0的内容。本书适合软件开发人员...
第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、...