java.util.concurrent 编程范例
来源:互联网 发布:tiva数据库 编辑:程序博客网 时间:2024/05/29 11:43
http://kanglecjr.iteye.com/blog/1070934
java.util.concurrent 范例之一
- 博客分类:
- Java
JavaTomcatthread
java.util.concurrent 之一
可能的运行结果:
上面是一个简单的例子。使用大小为2的线程池来处理10个线程。
它使用了Executors的静态函数 newFixedThreadPool() 生成一个固定的线程池。顾名思义,
线程池是不会释放的,即使它是Idle。这就会产生性能问题。比如如果线程池的大小为200,当全部使用完毕后,
所有的线程会继续留在池中,相应的内存和线程切换(while(true)+sleep)都会增加。如果要避免这个问题,就
必须直接使用ThreadPoolExecutor()来构造。可以像Tomcat的线程池一样,设置“最大线程数”、“最小线程数”
和“空闲线程keepAlive的时间”。通过这些可以基本上替换Tomcat的线程池实现方案。
需要注意的是线程池必须使用shutdown来显式关闭,否则主线程就无法退出。
- package test;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- public class TestThreadPool {
- public static void main(String args[]) throws InterruptedException{
- // only two threads
- ExecutorService exec = Executors.newFixedThreadPool(2);
- for(int index=0; index < 10; index++){
- Runnable run = new Runnable(){
- public void run(){
- long time = (long)(Math.random() * 1000);
- System.out.println("Sleeping " + time + "ms");
- try{
- Thread.sleep(time);
- } catch(InterruptedException e){
- }
- }
- };
- exec.execute(run);
- } // must shutdown
- exec.shutdown();
- }
- }
package test;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class TestThreadPool {public static void main(String args[]) throws InterruptedException{// only two threadsExecutorService exec = Executors.newFixedThreadPool(2);for(int index=0; index < 10; index++){Runnable run = new Runnable(){public void run(){long time = (long)(Math.random() * 1000);System.out.println("Sleeping " + time + "ms");try{Thread.sleep(time);}catch(InterruptedException e){}}};exec.execute(run);}// must shutdownexec.shutdown();}}
可能的运行结果:
- Sleeping 543ms
- Sleeping 33ms
- Sleeping 658ms
- Sleeping 740ms
- Sleeping 145ms
- Sleeping 216ms
- Sleeping 890ms
- Sleeping 864ms
- Sleeping 786ms
- Sleeping 644ms
Sleeping 543msSleeping 33msSleeping 658msSleeping 740msSleeping 145msSleeping 216msSleeping 890msSleeping 864msSleeping 786msSleeping 644ms
上面是一个简单的例子。使用大小为2的线程池来处理10个线程。
它使用了Executors的静态函数 newFixedThreadPool() 生成一个固定的线程池。顾名思义,
线程池是不会释放的,即使它是Idle。这就会产生性能问题。比如如果线程池的大小为200,当全部使用完毕后,
所有的线程会继续留在池中,相应的内存和线程切换(while(true)+sleep)都会增加。如果要避免这个问题,就
必须直接使用ThreadPoolExecutor()来构造。可以像Tomcat的线程池一样,设置“最大线程数”、“最小线程数”
和“空闲线程keepAlive的时间”。通过这些可以基本上替换Tomcat的线程池实现方案。
需要注意的是线程池必须使用shutdown来显式关闭,否则主线程就无法退出。
java.util.concurrent 范例之二:周期性运行
http://kanglecjr.iteye.com/blog/1071022
- package test;
- import static java.util.concurrent.TimeUnit.SECONDS;
- import java.util.Date;
- import java.util.concurrent.Executors;
- import java.util.concurrent.ScheduledExecutorService;
- import java.util.concurrent.ScheduledFuture;
- public class TestScheduledThread {
- /**
- * @param args
- */
- public static void main(String[] args) {
- final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
- final Runnable beeper = new Runnable() {
- int count = 0;
- public void run() {
- System.out.println(new Date() + " beep " + (++count));
- }
- };
- // 1秒钟后运行,并每隔2秒运行一次
- final ScheduledFuture beeperHandle = scheduler.scheduleAtFixedRate(beeper, 1, 2, SECONDS);
- // 2秒钟后运行,并每次在上次任务运行完后等待5秒后重新运行
- final ScheduledFuture beeperHandle2 = scheduler.scheduleWithFixedDelay(beeper, 2, 5, SECONDS);
- // 30秒后结束关闭任务,并且关闭Scheduler
- scheduler.schedule(new Runnable() {
- public void run() {
- beeperHandle.cancel(true);
- beeperHandle2.cancel(true);
- scheduler.shutdown();
- }
- }, 30, SECONDS);
- }
- }
package test;import static java.util.concurrent.TimeUnit.SECONDS;import java.util.Date;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.ScheduledFuture;public class TestScheduledThread {/** * @param args */public static void main(String[] args) { final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2); final Runnable beeper = new Runnable() { int count = 0; public void run() { System.out.println(new Date() + " beep " + (++count)); } }; // 1秒钟后运行,并每隔2秒运行一次 final ScheduledFuture beeperHandle = scheduler.scheduleAtFixedRate(beeper, 1, 2, SECONDS); // 2秒钟后运行,并每次在上次任务运行完后等待5秒后重新运行 final ScheduledFuture beeperHandle2 = scheduler.scheduleWithFixedDelay(beeper, 2, 5, SECONDS); // 30秒后结束关闭任务,并且关闭Scheduler scheduler.schedule(new Runnable() { public void run() { beeperHandle.cancel(true); beeperHandle2.cancel(true); scheduler.shutdown(); } }, 30, SECONDS);}}
可能的运行结果:
- Mon Jun 06 21:26:52 CST 2011 beep 1
- Mon Jun 06 21:26:53 CST 2011 beep 2
- Mon Jun 06 21:26:54 CST 2011 beep 3
- Mon Jun 06 21:26:56 CST 2011 beep 4
- Mon Jun 06 21:26:58 CST 2011 beep 5
- Mon Jun 06 21:26:58 CST 2011 beep 6
- Mon Jun 06 21:27:00 CST 2011 beep 7
- Mon Jun 06 21:27:02 CST 2011 beep 8
- Mon Jun 06 21:27:03 CST 2011 beep 9
- Mon Jun 06 21:27:04 CST 2011 beep 10
- Mon Jun 06 21:27:06 CST 2011 beep 11
- Mon Jun 06 21:27:08 CST 2011 beep 12
- Mon Jun 06 21:27:08 CST 2011 beep 13
- Mon Jun 06 21:27:10 CST 2011 beep 14
- Mon Jun 06 21:27:12 CST 2011 beep 15
- Mon Jun 06 21:27:13 CST 2011 beep 16
- Mon Jun 06 21:27:14 CST 2011 beep 17
- Mon Jun 06 21:27:16 CST 2011 beep 18
- Mon Jun 06 21:27:18 CST 2011 beep 19
- Mon Jun 06 21:27:18 CST 2011 beep 20
- Mon Jun 06 21:27:20 CST 2011 beep 21
Mon Jun 06 21:26:52 CST 2011 beep 1Mon Jun 06 21:26:53 CST 2011 beep 2Mon Jun 06 21:26:54 CST 2011 beep 3Mon Jun 06 21:26:56 CST 2011 beep 4Mon Jun 06 21:26:58 CST 2011 beep 5Mon Jun 06 21:26:58 CST 2011 beep 6Mon Jun 06 21:27:00 CST 2011 beep 7Mon Jun 06 21:27:02 CST 2011 beep 8Mon Jun 06 21:27:03 CST 2011 beep 9Mon Jun 06 21:27:04 CST 2011 beep 10Mon Jun 06 21:27:06 CST 2011 beep 11Mon Jun 06 21:27:08 CST 2011 beep 12Mon Jun 06 21:27:08 CST 2011 beep 13Mon Jun 06 21:27:10 CST 2011 beep 14Mon Jun 06 21:27:12 CST 2011 beep 15Mon Jun 06 21:27:13 CST 2011 beep 16Mon Jun 06 21:27:14 CST 2011 beep 17Mon Jun 06 21:27:16 CST 2011 beep 18Mon Jun 06 21:27:18 CST 2011 beep 19Mon Jun 06 21:27:18 CST 2011 beep 20Mon Jun 06 21:27:20 CST 2011 beep 21
许多长时间运行的应用有时候需要定时运行任务完成一些诸如统计、优化等工作,比如在电信行业中处理用户话单时,需要每隔1分钟处理话单;网站每天凌晨统计用户访问量、用户数;大型超市凌晨3点统计当天销售额、以及最热卖的商品;每周日进行数据库备份;公司每个月的10号计算工资并进行转帐等,这些都是定时任务。通过 java 的并发库concurrent可以轻松的完成这些任务,而且非常的简单。
为了退出进程,上面的代码中加入了关闭Scheduler的操作。而对于24小时运行的应用而言,是没有必要关闭Scheduler的。
http://kanglecjr.iteye.com/blog/1071042
java.util.concurrent 之三: 出发--等待--汇合--再出发
- 博客分类:
- Java
Javathread旅游工作
在实际应用中,有时候需要多个线程同时工作以完成同一件事情,而且在完成过程中,往往会等待其他线程都完成某一阶段后再执行,等所有线程都到达某一个阶段后再统一执行。
比如有几个旅行团需要途经深圳、广州、韶关、长沙最后到达武汉。旅行团中有自驾游的,有徒步的,有乘坐旅游大巴的;这些旅行团同时出发,并且每到一个目的地,都要等待其他旅行团到达此地后再同时出发,直到都到达终点站武汉。
这时候 CyclicBarrier 就可以派上用场。CyclicBarrier最重要的属性就是参与者个数,另外最要方法是await()。当所有线程都调用了await()后,就表示这些线程都可以继续执行,否则就会等待。
可能的执行结果:
比如有几个旅行团需要途经深圳、广州、韶关、长沙最后到达武汉。旅行团中有自驾游的,有徒步的,有乘坐旅游大巴的;这些旅行团同时出发,并且每到一个目的地,都要等待其他旅行团到达此地后再同时出发,直到都到达终点站武汉。
这时候 CyclicBarrier 就可以派上用场。CyclicBarrier最重要的属性就是参与者个数,另外最要方法是await()。当所有线程都调用了await()后,就表示这些线程都可以继续执行,否则就会等待。
- package test;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.concurrent.BrokenBarrierException;
- import java.util.concurrent.CyclicBarrier;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- public class TestCyclicBarrier{
- // 徒步需要的時間
- private static int[] timeWalk = { 5, 8, 15, 15, 10 };
- // 自駕遊
- private static int[] timeSelf = { 1, 3, 4, 4, 5 };
- // 旅遊大巴
- private static int[] timeBus = { 2,4,6,6,7 };
- static String now(){
- SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
- return sdf.format(new Date()) + ": ";
- }
- static class Tour implements Runnable{
- private int[] times;
- private CyclicBarrier barrier;
- private String tourName;
- public Tour(CyclicBarrier barrier, String tourName, int[] times){
- this.times=times;
- this.tourName=tourName;
- this.barrier=barrier;
- }
- public void run(){
- try{
- Thread.sleep(times[0]*1000);
- System.out.println(now() + tourName + " Reached Shenzhen");
- barrier.await();
- Thread.sleep(times[1]*1000);
- System.out.println(now() + tourName + " Reached Guangzhou");
- barrier.await();
- Thread.sleep(times[2]*1000);
- System.out.println(now() + tourName + " Reached Shaoguan");
- barrier.await();
- Thread.sleep(times[3]*1000);
- System.out.println(now() + tourName + " Reached Changsha");
- barrier.await();
- Thread.sleep(times[4]*1000);
- System.out.println(now() + tourName + " Reached Wuhan");
- barrier.await();
- }catch(InterruptedException e){
- }catch(BrokenBarrierException e){
- }
- }
- }
- public static void main(String[] args){
- // 三個旅行團
- CyclicBarrier barrier = new CyclicBarrier(3);
- ExecutorService exec = Executors.newFixedThreadPool(3);
- exec.submit(new Tour(barrier, "WalkTour", timeWalk));
- exec.submit(new Tour(barrier, "SelfTour", timeSelf));
- //
- exec.submit(new Tour(barrier, "BusTour", timeBus));
- exec.shutdown();
- }
- }
package test;import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class TestCyclicBarrier{// 徒步需要的時間private static int[] timeWalk = { 5, 8, 15, 15, 10 };// 自駕遊private static int[] timeSelf = { 1, 3, 4, 4, 5 };// 旅遊大巴private static int[] timeBus = { 2,4,6,6,7 };static String now(){SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");return sdf.format(new Date()) + ": ";}static class Tour implements Runnable{private int[] times;private CyclicBarrier barrier;private String tourName;public Tour(CyclicBarrier barrier, String tourName, int[] times){this.times=times;this.tourName=tourName;this.barrier=barrier;}public void run(){try{Thread.sleep(times[0]*1000);System.out.println(now() + tourName + " Reached Shenzhen");barrier.await();Thread.sleep(times[1]*1000);System.out.println(now() + tourName + " Reached Guangzhou");barrier.await();Thread.sleep(times[2]*1000);System.out.println(now() + tourName + " Reached Shaoguan");barrier.await();Thread.sleep(times[3]*1000);System.out.println(now() + tourName + " Reached Changsha");barrier.await();Thread.sleep(times[4]*1000);System.out.println(now() + tourName + " Reached Wuhan");barrier.await();}catch(InterruptedException e){}catch(BrokenBarrierException e){}}}public static void main(String[] args){// 三個旅行團CyclicBarrier barrier = new CyclicBarrier(3);ExecutorService exec = Executors.newFixedThreadPool(3);exec.submit(new Tour(barrier, "WalkTour", timeWalk));exec.submit(new Tour(barrier, "SelfTour", timeSelf));//exec.submit(new Tour(barrier, "BusTour", timeBus));exec.shutdown(); }}
可能的执行结果:
- 21:47:18: SelfTour Reached Shenzhen
- 21:47:19: BusTour Reached Shenzhen
- 21:47:22: WalkTour Reached Shenzhen
- 21:47:25: SelfTour Reached Guangzhou
- 21:47:26: BusTour Reached Guangzhou
- 21:47:30: WalkTour Reached Guangzhou
- 21:47:34: SelfTour Reached Shaoguan
- 21:47:36: BusTour Reached Shaoguan
- 21:47:45: WalkTour Reached Shaoguan
- 21:47:49: SelfTour Reached Changsha
- 21:47:51: BusTour Reached Changsha
- 21:48:00: WalkTour Reached Changsha
- 21:48:05: SelfTour Reached Wuhan
- 21:48:07: BusTour Reached Wuhan
- 21:48:10: WalkTour Reached Wuhan
http://kanglecjr.iteye.com/blog/1071069
java.util.concurrent 之四:LinkedBlockingQueue
- 博客分类:
- Java
Javathread
并发库中的BlockingQueue是一个比较好玩的类,顾名思义,就是阻塞队列。该类主要提供了两个方法put()和take(),前者将一个对象放到队列尾部,如果队列已经满了,就等待直到有空闲节点;后者从head取一个对象,如果没有对象,就等待直到有可取的对象。
可能的运行结果:
- package test;
- import java.util.concurrent.BlockingQueue;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.LinkedBlockingQueue;
- public class MyBlockingQueue extends Thread{
- public static BlockingQueue<String> queue=new LinkedBlockingQueue<String>(3);
- private int index;
- public MyBlockingQueue(int i){
- this.index=i;
- }
- public void run(){
- try{
- queue.put(String.valueOf(this.index));
- System.out.println("put {"+this.index+"} into queue!");
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- public static void main(String args[]){
- ExecutorService service=Executors.newCachedThreadPool();
- for( int i=0; i<10; i++){
- service.submit(new MyBlockingQueue(i));
- }
- Thread thread = new Thread(){
- public void run(){
- try{
- while(true){
- Thread.sleep((int)(Math.random()*1000));
- if(MyBlockingQueue.queue.isEmpty()) break;
- String str=MyBlockingQueue.queue.take();
- System.out.println("take {" + str+"} out of queue!");
- }
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- };
- service.submit(thread);
- service.shutdown();
- }
- }
package test;import java.util.concurrent.BlockingQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.LinkedBlockingQueue;public class MyBlockingQueue extends Thread{public static BlockingQueue<String> queue=new LinkedBlockingQueue<String>(3);private int index;public MyBlockingQueue(int i){this.index=i;}public void run(){try{queue.put(String.valueOf(this.index));System.out.println("put {"+this.index+"} into queue!");}catch(Exception e){e.printStackTrace();}}public static void main(String args[]){ExecutorService service=Executors.newCachedThreadPool();for( int i=0; i<10; i++){service.submit(new MyBlockingQueue(i));}Thread thread = new Thread(){public void run(){try{while(true){Thread.sleep((int)(Math.random()*1000));if(MyBlockingQueue.queue.isEmpty()) break;String str=MyBlockingQueue.queue.take();System.out.println("take {" + str+"} out of queue!");}}catch(Exception e){e.printStackTrace();}}};service.submit(thread);service.shutdown();}}
可能的运行结果:
- put {0} into queue!
- put {1} into queue!
- put {3} into queue!
- take {0} out of queue!
- put {2} into queue!
- take {1} out of queue!
- put {7} into queue!
- take {3} out of queue!
- put {5} into queue!
- take {2} out of queue!
- put {4} into queue!
- take {7} out of queue!
- put {6} into queue!
- put {9} into queue!
- take {5} out of queue!
- take {4} out of queue!
- put {8} into queue!
- take {6} out of queue!
- take {9} out of queue!
- take {8} out of queue!
http://kanglecjr.iteye.com/blog/1071107
java.util.concurrent 之五:倒计数的锁
- 博客分类:
- Java
Javathread
从名字可以看出,CountDownLatch是一个倒数计数的锁,当倒数到0时触发事件,也就是开锁,其他人就可以进入了。在一些应用场合中,需要等待某个条件达到要求后才能做后面的事情;同时当线程都完成后也会触发事件,以便进行后面的操作。
CountDownLatch最重要的方法是countDown()和await(),前者主要是倒数一次,后者是等待倒数到0,如果没有到达0,就只有阻塞等待了。
一个CountDownLatch实例是不能重复使用的,也就是说它是一次性的,锁一经被打开就不能再关闭使用了,如果想重复使用,请考虑使用CyclicBarrier。
下面的例子简单的说明了CountDownLatch的使用方法,模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束。
同样,线程池需要显式shutdown。
可能的结果:
CountDownLatch最重要的方法是countDown()和await(),前者主要是倒数一次,后者是等待倒数到0,如果没有到达0,就只有阻塞等待了。
一个CountDownLatch实例是不能重复使用的,也就是说它是一次性的,锁一经被打开就不能再关闭使用了,如果想重复使用,请考虑使用CyclicBarrier。
下面的例子简单的说明了CountDownLatch的使用方法,模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束。
同样,线程池需要显式shutdown。
- package test;
- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- public class TestCountDownLatch{
- public static void main(String[] args) throws InterruptedException{
- //开始的倒数锁
- final CountDownLatch begin=new CountDownLatch(1);
- //结束的倒数锁
- final CountDownLatch end=new CountDownLatch(10);
- //10名选手
- final ExecutorService exec=Executors.newFixedThreadPool(10);
- for(int index=0; index<10;index++){
- final int NO=index + 1;//Cannot refer to a non-final variable NO inside an inner class defined in a different method
- Runnable run=new Runnable(){
- public void run(){
- try{
- begin.await();//一直阻塞
- Thread.sleep((long)(Math.random() * 10000));
- System.out.println("No." + NO + " arrived");
- }catch(InterruptedException e){
- }finally{
- end.countDown();
- }
- }
- };
- exec.submit(run);
- }
- System.out.println("Game Start");
- begin.countDown();
- end.await();
- System.out.println("Game Over");
- exec.shutdown();
- }
- }
package test;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class TestCountDownLatch{public static void main(String[] args) throws InterruptedException{//开始的倒数锁final CountDownLatch begin=new CountDownLatch(1);//结束的倒数锁final CountDownLatch end=new CountDownLatch(10);//10名选手final ExecutorService exec=Executors.newFixedThreadPool(10);for(int index=0; index<10;index++){final int NO=index + 1;//Cannot refer to a non-final variable NO inside an inner class defined in a different methodRunnable run=new Runnable(){public void run(){try{begin.await();//一直阻塞Thread.sleep((long)(Math.random() * 10000));System.out.println("No." + NO + " arrived");}catch(InterruptedException e){}finally{end.countDown();}}};exec.submit(run);}System.out.println("Game Start");begin.countDown();end.await();System.out.println("Game Over");exec.shutdown();}}
可能的结果:
- Game Start
- No.4 arrived
- No.6 arrived
- No.8 arrived
- No.5 arrived
- No.10 arrived
- No.3 arrived
- No.2 arrived
- No.7 arrived
- No.1 arrived
- No.9 arrived
- Game Over
http://kanglecjr.iteye.com/blog/1071199java.util.concurrent 之六:使用Future类和Callable类
博客分类:- Java
Java浏览器thread 有时候在实际应用中,某些操作很耗时,但又不是不可或缺的步骤。比如用网页浏览器浏览新闻时,最重要的是显示文字内容,至于与新闻相匹配的图片就没有那么重要的,所以此时首先保证文字信息先显示,而图片信息会后显示,但又不能不显示,由于下载图片是一个耗时的操作,所以必须一开始就得下载。
Java的并发库的Future类就可以满足这个要求。Future的重要方法包括get()和cancel(),get()获取数据对象,如果数据没有加载,就会阻塞直到取到数据,而cancel()是取消数据加载。另外一个get(timeout)操作,表示如果在timeout时间内没有取到就失败返回,而不再阻塞。
下面的Demo简单的说明了Future的使用方法:一个非常耗时的操作必须一开始启动,但又不能一直等待;其他重要的事情又必须做,等完成后,就可以做不重要的事情。
- package concurrent;
-
- import java.util.concurrent.Callable;
- import java.util.concurrent.ExecutionException;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Future;
-
- public class TestFutureTask {
- public static void main(String[] args) throws InterruptedException,ExecutionException{
- final ExecutorService exec = Executors.newFixedThreadPool(5);
-
- Callable call = new Callable(){
- public String call() throws Exception{
- Thread.sleep(1000 * 5);
- return "Other less important but longtime things.";
- }
- };
- Future task = exec.submit(call);
- //重要的事情
- Thread.sleep(1000 * 3);
- System.out.println("Let's do important things.");
- //其他不重要的事情
- String obj = (String)task.get();
- System.out.println(obj);
- //关闭线程池
- exec.shutdown();
- }
- }
package concurrent;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class TestFutureTask {public static void main(String[] args) throws InterruptedException,ExecutionException{final ExecutorService exec = Executors.newFixedThreadPool(5);Callable call = new Callable(){public String call() throws Exception{Thread.sleep(1000 * 5);return "Other less important but longtime things.";}};Future task = exec.submit(call);//重要的事情Thread.sleep(1000 * 3);System.out.println("Let's do important things.");//其他不重要的事情String obj = (String)task.get();System.out.println(obj);//关闭线程池exec.shutdown();}}
运行结果:
- Let's do important things.
- Other less important but longtime things.
Let's do important things.Other less important but longtime things.
http://kanglecjr.iteye.com/blog/1071200java.util.concurrent 之七:先下载完成的图片先显示
博客分类:- Java
Java浏览器Webthread考虑以下场景:浏览网页时,浏览器用了5个线程下载网页中的图片文件,由于图片大小、网站访问速度等诸多因素的影响,完成图片下载的时间就会有很大的不同。先下载完成的图片就会被先显示到界面上,反之,后下载的图片就后显示。
Java的并发库的CompletionService可以满足这种场景要求。该接口有两个重要方法:submit()和take()。submit用于提交一个runnable或者callable,一般会提交给一个线程池处理;而take就是取出已经执行完毕runnable或者callable实例的Future对象,如果没有满足要求的,就等待了。CompletionService还有一个对应的方法poll,该方法与take类似,只是不会等待,如果没有满足要求,就返回null对象。
- package concurrent;
-
- import java.util.concurrent.Callable;
- import java.util.concurrent.CompletionService;
- import java.util.concurrent.ExecutionException;
- import java.util.concurrent.ExecutorCompletionService;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Future;
-
- public class TestCompletionService {
- public static void main(String[] args) throws InterruptedException, ExecutionException{
- ExecutorService exec = Executors.newFixedThreadPool(10);
- CompletionService serv = new ExecutorCompletionService(exec);
-
- for(int index = 0; index < 5; index++){
- final int NO = index;
- Callable downImg = new Callable(){
- public String call() throws Exception{
- Thread.sleep((long)(Math.random() * 10000));
- return "Downloaded Image " + NO;
- }
- };
- serv.submit(downImg);
- }
-
- Thread.sleep(1000*2);
- System.out.println("Show web content");
- for(int index=0; index<5; index++){
- Future task = serv.take();
- String img = (String)task.get();
- System.out.println(img);
- }
- System.out.println("End");
- //关闭线程池
- exec.shutdown();
- }
- }
package concurrent;import java.util.concurrent.Callable;import java.util.concurrent.CompletionService;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorCompletionService;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class TestCompletionService {public static void main(String[] args) throws InterruptedException, ExecutionException{ExecutorService exec = Executors.newFixedThreadPool(10);CompletionService serv = new ExecutorCompletionService(exec);for(int index = 0; index < 5; index++){final int NO = index;Callable downImg = new Callable(){public String call() throws Exception{Thread.sleep((long)(Math.random() * 10000));return "Downloaded Image " + NO;}};serv.submit(downImg);}Thread.sleep(1000*2);System.out.println("Show web content");for(int index=0; index<5; index++){Future task = serv.take();String img = (String)task.get();System.out.println(img);}System.out.println("End");//关闭线程池exec.shutdown();}}
运行结果:
- Show web content
- Downloaded Image 2
- Downloaded Image 3
- Downloaded Image 0
- Downloaded Image 4
- Downloaded Image 1
- End
http://kanglecjr.iteye.com/blog/1071199
java.util.concurrent 之六:使用Future类和Callable类
- 博客分类:
- Java
Java浏览器thread
有时候在实际应用中,某些操作很耗时,但又不是不可或缺的步骤。比如用网页浏览器浏览新闻时,最重要的是显示文字内容,至于与新闻相匹配的图片就没有那么重要的,所以此时首先保证文字信息先显示,而图片信息会后显示,但又不能不显示,由于下载图片是一个耗时的操作,所以必须一开始就得下载。
Java的并发库的Future类就可以满足这个要求。Future的重要方法包括get()和cancel(),get()获取数据对象,如果数据没有加载,就会阻塞直到取到数据,而cancel()是取消数据加载。另外一个get(timeout)操作,表示如果在timeout时间内没有取到就失败返回,而不再阻塞。
下面的Demo简单的说明了Future的使用方法:一个非常耗时的操作必须一开始启动,但又不能一直等待;其他重要的事情又必须做,等完成后,就可以做不重要的事情。
运行结果:
Java的并发库的Future类就可以满足这个要求。Future的重要方法包括get()和cancel(),get()获取数据对象,如果数据没有加载,就会阻塞直到取到数据,而cancel()是取消数据加载。另外一个get(timeout)操作,表示如果在timeout时间内没有取到就失败返回,而不再阻塞。
下面的Demo简单的说明了Future的使用方法:一个非常耗时的操作必须一开始启动,但又不能一直等待;其他重要的事情又必须做,等完成后,就可以做不重要的事情。
- package concurrent;
- import java.util.concurrent.Callable;
- import java.util.concurrent.ExecutionException;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Future;
- public class TestFutureTask {
- public static void main(String[] args) throws InterruptedException,ExecutionException{
- final ExecutorService exec = Executors.newFixedThreadPool(5);
- Callable call = new Callable(){
- public String call() throws Exception{
- Thread.sleep(1000 * 5);
- return "Other less important but longtime things.";
- }
- };
- Future task = exec.submit(call);
- //重要的事情
- Thread.sleep(1000 * 3);
- System.out.println("Let's do important things.");
- //其他不重要的事情
- String obj = (String)task.get();
- System.out.println(obj);
- //关闭线程池
- exec.shutdown();
- }
- }
package concurrent;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class TestFutureTask {public static void main(String[] args) throws InterruptedException,ExecutionException{final ExecutorService exec = Executors.newFixedThreadPool(5);Callable call = new Callable(){public String call() throws Exception{Thread.sleep(1000 * 5);return "Other less important but longtime things.";}};Future task = exec.submit(call);//重要的事情Thread.sleep(1000 * 3);System.out.println("Let's do important things.");//其他不重要的事情String obj = (String)task.get();System.out.println(obj);//关闭线程池exec.shutdown();}}
运行结果:
- Let's do important things.
- Other less important but longtime things.
Let's do important things.Other less important but longtime things.
http://kanglecjr.iteye.com/blog/1071200
java.util.concurrent 之七:先下载完成的图片先显示
- 博客分类:
- Java
Java浏览器Webthread
考虑以下场景:浏览网页时,浏览器用了5个线程下载网页中的图片文件,由于图片大小、网站访问速度等诸多因素的影响,完成图片下载的时间就会有很大的不同。先下载完成的图片就会被先显示到界面上,反之,后下载的图片就后显示。
Java的并发库的CompletionService可以满足这种场景要求。该接口有两个重要方法:submit()和take()。submit用于提交一个runnable或者callable,一般会提交给一个线程池处理;而take就是取出已经执行完毕runnable或者callable实例的Future对象,如果没有满足要求的,就等待了。CompletionService还有一个对应的方法poll,该方法与take类似,只是不会等待,如果没有满足要求,就返回null对象。
运行结果:
Java的并发库的CompletionService可以满足这种场景要求。该接口有两个重要方法:submit()和take()。submit用于提交一个runnable或者callable,一般会提交给一个线程池处理;而take就是取出已经执行完毕runnable或者callable实例的Future对象,如果没有满足要求的,就等待了。CompletionService还有一个对应的方法poll,该方法与take类似,只是不会等待,如果没有满足要求,就返回null对象。
- package concurrent;
- import java.util.concurrent.Callable;
- import java.util.concurrent.CompletionService;
- import java.util.concurrent.ExecutionException;
- import java.util.concurrent.ExecutorCompletionService;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Future;
- public class TestCompletionService {
- public static void main(String[] args) throws InterruptedException, ExecutionException{
- ExecutorService exec = Executors.newFixedThreadPool(10);
- CompletionService serv = new ExecutorCompletionService(exec);
- for(int index = 0; index < 5; index++){
- final int NO = index;
- Callable downImg = new Callable(){
- public String call() throws Exception{
- Thread.sleep((long)(Math.random() * 10000));
- return "Downloaded Image " + NO;
- }
- };
- serv.submit(downImg);
- }
- Thread.sleep(1000*2);
- System.out.println("Show web content");
- for(int index=0; index<5; index++){
- Future task = serv.take();
- String img = (String)task.get();
- System.out.println(img);
- }
- System.out.println("End");
- //关闭线程池
- exec.shutdown();
- }
- }
package concurrent;import java.util.concurrent.Callable;import java.util.concurrent.CompletionService;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorCompletionService;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class TestCompletionService {public static void main(String[] args) throws InterruptedException, ExecutionException{ExecutorService exec = Executors.newFixedThreadPool(10);CompletionService serv = new ExecutorCompletionService(exec);for(int index = 0; index < 5; index++){final int NO = index;Callable downImg = new Callable(){public String call() throws Exception{Thread.sleep((long)(Math.random() * 10000));return "Downloaded Image " + NO;}};serv.submit(downImg);}Thread.sleep(1000*2);System.out.println("Show web content");for(int index=0; index<5; index++){Future task = serv.take();String img = (String)task.get();System.out.println(img);}System.out.println("End");//关闭线程池exec.shutdown();}}
运行结果:
- Show web content
- Downloaded Image 2
- Downloaded Image 3
- Downloaded Image 0
- Downloaded Image 4
- Downloaded Image 1
- End
- java.util.concurrent 编程范例
- java.util.concurrent.Exchanger应用范例与原理浅析
- java.util.concurrent.Exchanger应用范例与原理浅析--转载
- 【多线程】java.util.concurrent.Exchanger应用范例与原理浅析
- java.util.concurrent.Exchanger应用范例与原理浅析
- java.util.concurrent.Exchanger应用范例与原理浅析
- java并发编程:java.util.concurrent
- java并发编程(3)--java.util.concurrent.*
- 【java】 java.util.concurrent
- java.util.concurrent.CyclicBarrier
- java.util.concurrent 学习
- java.util.concurrent包
- java.util.concurrent 架构
- java.util.concurrent
- 关于 java.util.concurrent
- java.util.concurrent.ThreadPoolExecutor
- java.util.concurrent介绍
- java.util.concurrent介绍
- printf参数
- Android用户界面---对话框(dialogs)
- 简洁明了,C++中动态定义一维数组,二维数组,三维数组
- 关于vpn拨号800错误的解决方法之一
- 给C++初学者的50个忠告
- java.util.concurrent 编程范例
- poj2201
- 不使用string而获取任意长度的字符串
- VC++6.0 MFC ClassView找不到对话框类的解决方法
- 【UVa10167】 Birthday Cake,思路+代码+解题报告
- wp7手机归属地查询源代码
- Microsoft Sql server 2008 简体中文开发版安装指南
- 一键让Windows锁屏+关屏
- 一个简单的Makefile