- 浏览: 139589 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
elephant_xiang:
condition例子,搞错了吧public void pro ...
jdk1.5的多线程总结一 -
yinlei126:
这么好的文章没有评论,谢谢
Mina框架剖析--动态篇 -
xds2008:
写的不错,值得表扬,测了一下,还不错,就是有点慢,但是最起码远 ...
java实现远程桌面监控 -
exp111:
这个确实很强 但是能不能连接一次不停的传呢 这个好像是必须连一 ...
java实现远程桌面监控 -
seeallsea:
不错!可以相互转换了。
keystore证书转换
新的Synchronizer:
Java 5.0里新加了4个协调线程间进程的同步装置,它们分别是Semaphore, CountDownLatch, CyclicBarrier和Exchanger。
Semaphore:
用来管理一个资源池的工具,Semaphore可以看成是个通行证,线程要想从资源池拿到资源必须先拿到通行证,Semaphore提供的通行证数量和资源池的大小一致。如果线程暂时拿不到通行证,线程就会被阻断进入等待状态。
CountDownLatch:
CountDownLatch是个计数器,它有一个初始数,等待这个计数器的线程必须等到计数器倒数到零时才可继续。比如说一个Server启动时需要初始化4个部件,Server可以同时启动4个线程去初始化这4个部件,然后调用CountDownLatch(4).await()阻断进入等待,每个线程完成任务后会调用一次CountDownLatch.countDown()来倒计数, 当4个线程都结束时CountDownLatch的计数就会降低为0,此时Server就会被唤醒继续下一步操作。CountDownLatch的方法主要有:
await():使调用此方法的线程阻断进入等待
countDown(): 倒计数,将计数值减1
getCount(): 得到当前的计数值
CyclicBarrier:
CyclicBarrier类似于CountDownLatch也是个计数器,不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数,当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。CyclicBarrier就象它名字的意思一样,可看成是个障碍,所有的线程必须到齐后才能一起通过这个障碍。CyclicBarrier初始时还可带一个Runnable的参数,此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。
CyclicBarrier提供以下几个方法:
await():进入等待
getParties():返回此barrier需要的线程数
reset():将此barrier重置
Exchanger:
让两个线程可以互换信息。这个跟生产消费模式有点不同,生产消费模式是生产者和消费者对同一个数据争用,这里是对两个同类型的数据争用,用完就互换。用一个例子来解释比较容易。例子中服务生线程往空的杯子里倒水,顾客线程从装满水的杯子里喝水,然后通过Exchanger双方互换杯子,服务生接着往空杯子里倒水,顾客接着喝水,然后交换,如此周而复始。两个线程同时只对自己的那个数据操作。
BlockingQueue接口
BlockingQueue是一种特殊的Queue,若BlockingQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态直到BlocingkQueue进了新货才会被唤醒。同样,如果BlockingQueue是满的任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有新的空间才会被唤醒继续操作。BlockingQueue提供的方法主要有:
add(anObject): 把anObject加到BlockingQueue里,如果BlockingQueue可以容纳返回true,否则抛出IllegalStateException异常。
offer(anObject):把anObject加到BlockingQueue里,如果BlockingQueue可以容纳返回true,否则返回false。
put(anObject):把anObject加到BlockingQueue里,如果BlockingQueue没有空间,调用此方法的线程被阻断直到BlockingQueue里有新的空间再继续。
poll(time):取出BlockingQueue里排在首位的对象,若不能立即取出可等time参数规定的时间。取不到时返回null。
take():取出BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的对象被加入为止。
根据不同的需要BlockingQueue有4种具体实现:
ArrayBlockingQueue:规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小。其所含的对象是以FIFO(先入先出)顺序排序的。
LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定。其所含的对象是以FIFO(先入先出)顺序排序的。LinkedBlockingQueue和ArrayBlockingQueue比较起来,它们背后所用的数据结构不一样,导致LinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue,但在线程数量很大时其性能的可预见性低于ArrayBlockingQueue。
PriorityBlockingQueue:类似于LinkedBlockingQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序。
SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的。
下面是用BlockingQueue来实现经典的Producer和Consumer模式
Atomics 原子级变量
主要的类有AtomicBoolean, AtomicInteger, AotmicIntegerArray, AtomicLong, AtomicLongArray, AtomicReference ……。这些原子量级的变量主要提供两个方法:
compareAndSet(expectedValue, newValue): 比较当前的值是否等于expectedValue,若等于把当前值改成newValue,并返回true。若不等,返回false。
getAndSet(newValue): 把当前值改为newValue,并返回改变前的值。
这些原子级变量利用了CPU的硬件支持可把两步操作合为一步的功能,避免了不必要的锁定,提高了程序的运行效率。
Java 5.0里新加了4个协调线程间进程的同步装置,它们分别是Semaphore, CountDownLatch, CyclicBarrier和Exchanger。
Semaphore:
用来管理一个资源池的工具,Semaphore可以看成是个通行证,线程要想从资源池拿到资源必须先拿到通行证,Semaphore提供的通行证数量和资源池的大小一致。如果线程暂时拿不到通行证,线程就会被阻断进入等待状态。
public class Pool { List<String> pool = null; Semaphore pass = null; public Pool(int size) { // 初始化资源池 pool = new ArrayList<String>(); for (int i = 0; i < size; 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("Take " + result); return result; } private synchronized void releaseResource(String resource) { System.out.println("return " + resource); pool.add(resource); } } 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(); } }
CountDownLatch:
CountDownLatch是个计数器,它有一个初始数,等待这个计数器的线程必须等到计数器倒数到零时才可继续。比如说一个Server启动时需要初始化4个部件,Server可以同时启动4个线程去初始化这4个部件,然后调用CountDownLatch(4).await()阻断进入等待,每个线程完成任务后会调用一次CountDownLatch.countDown()来倒计数, 当4个线程都结束时CountDownLatch的计数就会降低为0,此时Server就会被唤醒继续下一步操作。CountDownLatch的方法主要有:
await():使调用此方法的线程阻断进入等待
countDown(): 倒计数,将计数值减1
getCount(): 得到当前的计数值
public class Server { public static void main(String[] args) throws InterruptedException{ //一个server调了三个ComponentThread分别去启动三个组件,然后server等到组件都启动了再继续 System.out.println("Server is starting."); //初始化一个初始值为3的CountDownLatch CountDownLatch latch = new CountDownLatch(3); //起3个线程分别去启动3个组件 ExecutorService service = Executors.newCachedThreadPool(); service.submit(new ComponentThread(latch, 1)); service.submit(new ComponentThread(latch, 2)); service.submit(new ComponentThread(latch, 3)); service.shutdown(); //进入等待状态 latch.await(); //当所需的三个组件都完成时,Server就可继续了 System.out.println("Server is up!"); } }
public class ComponentThread implements Runnable { CountDownLatch latch; int ID; public ComponentThread(CountDownLatch latch, int ID) { this.latch = latch; this.ID = ID; } public void run() { System.out.println("Component " + ID + " initialized!"); // 将计数减一 latch.countDown(); } }
CyclicBarrier:
CyclicBarrier类似于CountDownLatch也是个计数器,不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数,当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。CyclicBarrier就象它名字的意思一样,可看成是个障碍,所有的线程必须到齐后才能一起通过这个障碍。CyclicBarrier初始时还可带一个Runnable的参数,此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。
CyclicBarrier提供以下几个方法:
await():进入等待
getParties():返回此barrier需要的线程数
reset():将此barrier重置
public class CyclicBarrierTest { public static void main(String[] args) throws InterruptedException, BrokenBarrierException, TimeoutException { // 两个线程分别在一个数组里放一个数,当这两个线程都结束后,主线程算出数组里的数的和 final int[] array = new int[2]; CyclicBarrier barrier = new CyclicBarrier(2, new Runnable() { public void run() { System.out.println("Total is:" + (array[0] + array[1])); } }); // 启动线程 new Thread(new ComponentThread(barrier, array, 0)).start(); new Thread(new ComponentThread(barrier, array, 1)).start(); } }
public class ComponentThread implements Runnable{ CyclicBarrier barrier; int ID; int[] array; public ComponentThread(CyclicBarrier barrier, int[] array, int ID) { this.barrier = barrier; this.ID = ID; this.array = array; } public void run() { try { array[ID] = new Random().nextInt(); System.out.println(ID+ " generates:"+array[ID]); //该线程完成了任务等在Barrier处 barrier.await(); } catch (BrokenBarrierException ex) { ex.printStackTrace(); } catch (InterruptedException ex) { ex.printStackTrace(); } } }
Exchanger:
让两个线程可以互换信息。这个跟生产消费模式有点不同,生产消费模式是生产者和消费者对同一个数据争用,这里是对两个同类型的数据争用,用完就互换。用一个例子来解释比较容易。例子中服务生线程往空的杯子里倒水,顾客线程从装满水的杯子里喝水,然后通过Exchanger双方互换杯子,服务生接着往空杯子里倒水,顾客接着喝水,然后交换,如此周而复始。两个线程同时只对自己的那个数据操作。
BlockingQueue接口
BlockingQueue是一种特殊的Queue,若BlockingQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态直到BlocingkQueue进了新货才会被唤醒。同样,如果BlockingQueue是满的任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有新的空间才会被唤醒继续操作。BlockingQueue提供的方法主要有:
add(anObject): 把anObject加到BlockingQueue里,如果BlockingQueue可以容纳返回true,否则抛出IllegalStateException异常。
offer(anObject):把anObject加到BlockingQueue里,如果BlockingQueue可以容纳返回true,否则返回false。
put(anObject):把anObject加到BlockingQueue里,如果BlockingQueue没有空间,调用此方法的线程被阻断直到BlockingQueue里有新的空间再继续。
poll(time):取出BlockingQueue里排在首位的对象,若不能立即取出可等time参数规定的时间。取不到时返回null。
take():取出BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的对象被加入为止。
根据不同的需要BlockingQueue有4种具体实现:
ArrayBlockingQueue:规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小。其所含的对象是以FIFO(先入先出)顺序排序的。
LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定。其所含的对象是以FIFO(先入先出)顺序排序的。LinkedBlockingQueue和ArrayBlockingQueue比较起来,它们背后所用的数据结构不一样,导致LinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue,但在线程数量很大时其性能的可预见性低于ArrayBlockingQueue。
PriorityBlockingQueue:类似于LinkedBlockingQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序。
SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的。
下面是用BlockingQueue来实现经典的Producer和Consumer模式
public class BlockingQueueTest { static BlockingQueue<String> basket; public BlockingQueueTest() { // 定义了一个大小为2的BlockingQueue,也可根据需要用其他的具体类 basket = new ArrayBlockingQueue<String>(2); } class Producor implements Runnable { public void run() { while (true) { try { // 放入一个对象,若basket满了,等到basket有位置 basket.put("An apple"); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } class Consumer implements Runnable { public void run() { while (true) { try { // 取出一个对象,若basket为空,等到basket有东西为止 String result = basket.take(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } public void execute() { for (int i = 0; i < 10; i++) { new Thread(new Producor()).start(); new Thread(new Consumer()).start(); } } public static void main(String[] args) { BlockingQueueTest test = new BlockingQueueTest(); test.execute(); } }
Atomics 原子级变量
主要的类有AtomicBoolean, AtomicInteger, AotmicIntegerArray, AtomicLong, AtomicLongArray, AtomicReference ……。这些原子量级的变量主要提供两个方法:
compareAndSet(expectedValue, newValue): 比较当前的值是否等于expectedValue,若等于把当前值改成newValue,并返回true。若不等,返回false。
getAndSet(newValue): 把当前值改为newValue,并返回改变前的值。
这些原子级变量利用了CPU的硬件支持可把两步操作合为一步的功能,避免了不必要的锁定,提高了程序的运行效率。
发表评论
-
Java上clear Squid缓存
2011-11-29 10:26 1278实现原理: 构造TCP请求,调用Squid自带 ... -
HttpURLConnection设置代理
2011-01-21 11:00 1463设置全局代理,JVM范围内有效: System ... -
JCE provider管理的问题
2010-08-23 13:24 3245现象 两个module A和B分别采用了infosec的不同版 ... -
Jar冲突解决二
2010-08-23 11:54 1742方案思想 自定义CustomClassLoader,彻底改变c ... -
Jar冲突解决一
2010-08-23 10:46 1222目的是classpath中线性的jar排列扩展成树型排列。方案 ... -
负载均衡备注二
2010-03-30 11:41 1089Lvs或者F5的负载体系中 ... -
SelectableChannel关闭注意事项
2010-03-29 11:49 993SocketChannel和ServerSocketChann ... -
java clone备忘
2009-12-09 14:39 8141.Object clone 就是复制一个对象的复本,在Fac ... -
远程调用之RMI
2009-05-22 00:03 1044RMI(Remote Method Invocation ... -
Java修饰符归纳
2009-05-20 17:26 920final 1.final类 final类不能被继承, ... -
classloader整理
2009-05-18 18:08 1113classloader它就是用来加载Class文件到JV ... -
Java IO归纳
2009-05-17 14:39 1651Java的IO基于装饰器模式设计。根接口是InputS ... -
java实现远程桌面监控
2009-05-10 19:28 3851java里面的Robot类可以完成截图的功能,借助于这 ... -
简单的轮子--IOC容器
2009-05-10 15:48 1133产品的需求越来越多,则开发了越来越多的功能,同时也带来了 ... -
Java也可以截图
2009-05-10 14:48 1115java.awt.Robot类真的很好玩。玩Robot会给你带 ... -
jdk1.5的多线程总结一
2009-05-10 01:17 6030Java 5.0里新加入了三个多线程包:java.util.c ... -
JavaGC知识整理
2009-05-08 00:55 961堆 JVM管理的内存叫堆。在32Bit操作系统上有1.5G-2 ... -
ConcurrentHashMap
2009-05-08 00:54 1021实现原理 锁分离 (Lock Stripping) C ... -
Java Socket异常整理
2009-05-08 00:41 3542最近跟进性能测试,碰 ... -
Java各种路径和参数
2009-05-08 00:39 12431.JSP中获得当前应用的 ...
相关推荐
总结来说,jxl.jar在JDK1.5和JDK1.6环境下都可以使用,但每个新版本的JDK都可能带来性能差异和潜在的兼容性问题。因此,进行详尽的测试和评估是确保项目稳定运行的关键。同时,开发者也需要关注和考虑更新的库和技术...
在Java编程语言中,线程并发和线程池是多任务执行的核心概念,尤其是在...熟练掌握这些工具,能帮助开发者编写出更加稳定、高效的多线程应用程序。通过深入学习和实践,可以更好地理解和利用这些特性,优化程序性能。
1. 并发库(Concurrent Utilities):引入了丰富的并发工具类,如`java.util.concurrent`包,包括线程池、并发集合等,极大地改善了多线程编程的效率和可靠性。 2. NIO.2(New I/O):增强了Java的I/O性能,增加了...
1. 并发工具库的改进:包括`java.util.concurrent`包中更多线程安全的数据结构和并发工具,如`ConcurrentHashMap`,`Phaser`等。 2. 轻量级注解处理:允许在编译时处理注解,无需生成额外的源代码或字节码。 3. 动态...
JDK 1.5增加了大量并发编程的工具类,如`java.util.concurrent`包下的`ExecutorService`、`Future`、`Semaphore`等,它们提供了更高效和安全的多线程处理方式。 **10. 遍历Map的键值对(For-Each Loop over Maps)*...
枚举在多线程、权限控制和设计模式等方面都有着广泛的应用,提升了代码的规范性和可维护性。 此外,JDK 1.5还推出了变量类型推断(varargs)功能,这使得方法可以接受任意数量的同一类型的参数。通过在方法声明中...
张孝祥的Java多线程与并发库高级应用笔记涵盖了从传统线程技术到JDK1.5并发库的全面内容,不仅加深了对线程基本原理的认识,还介绍了现代Java并发编程的最佳实践。对于希望提升多线程编程技能的Java开发者来说,这是...
9. **并发编程改进**:引入了`java.util.concurrent`包,包含线程池、并发集合等工具,提高了多线程程序的编写效率和性能。 **环境变量配置** 安装JDK 1.5 Update 22后,为了能正确运行Java程序,需要设置一些系统...
这只是一个基础的示例,实际使用中,jcifs库可以处理更复杂的情况,如多线程访问、错误处理和高级权限控制。 总结来说,jcifs库为Java开发者提供了一个强大且灵活的工具,使他们能够在Java应用程序中无缝地集成CIFS...
描述中提到"linux版的jdk1.5,官网下载",这确认了JDK的版本是1.5,也被称为Java 5,它是在Linux平台上官方提供的版本,并且是从官方网站下载的。Java 5是一个重要的Java版本,引入了许多新特性,对Java语言的演进...
总结来说,Java多线程与并发库的高级应用,既包括了传统的多线程编程技术,也包含了JDK 1.5之后引入的高级并发工具和特性。掌握这些知识点对于任何想要在Java编程领域深入发展的开发者来说,都是非常必要的。
JDK1.6是Java发展史上的一个重要版本,它在JDK1.5的基础上进行了大量的改进和优化,提供了更多的特性和功能。 ### 二、JDK1.6的主要特性 1. **性能优化**:JDK1.6对垃圾回收机制进行了改进,提升了程序运行时的...
4. 多线程改进:JDK 1.6增强了线程管理,包括线程池的改进,使得开发者可以更有效地控制线程的生命周期和资源分配。 5. 新的Swing组件:JDK 1.6对Swing库进行了更新,增加了新的组件和布局管理器,提升了图形用户...
JDK 1.8引入了一些重要的新特性,如Lambda表达式、Stream API、方法引用来简化代码,以及接口的默认方法和静态方法,增强了多线程处理的并发工具类等。这些特性极大地提高了Java开发的效率和代码的可读性。 总结来...
2. **网络与多线程**:如java.net和java.nio包,支持网络通信;java.concurrent包提供了高级并发和线程管理工具。 3. **图形界面**:java.awt和javax.swing包提供了图形用户界面(GUI)组件和布局管理器。 4. **...
- **泛型**:JDK 1.5引入了泛型,允许在定义类、接口和方法时指定参数类型,提高了代码的类型安全性和重用性。 - **增强的for循环(foreach)**:简化了遍历集合和其他迭代器支持的数据结构的代码。 - **动态代理*...
9. **并发编程工具**:`java.util.concurrent`包中的类和接口进一步丰富,如CountDownLatch、CyclicBarrier和ForkJoinPool等,使得多线程编程更为方便。 10. **JMX(Java Management Extensions)**:提供了更强大...
#### 五、JDK1.5之后的高级同步工具 1. **`ReentrantLock`**: - `ReentrantLock`是Java 1.5之后引入的一个可中断、可轮询、可定时的锁。 - 示例代码: ```java private ReentrantLock lock = new ...