仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 395|回复: 11
打印 上一主题 下一主题

[学习教程] JAVA网站制作之Java:多线程守候一切线程停止(CountDownLatch/CyclicBarrier) .仓酷云

[复制链接]
简单生活 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:23:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
恰恰证明了java的简单,要不怎么没有通过c/c++来搞个这种框架?本文次要是参考官方文档做一进修用处。
官方链接:
  1. http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html
复制代码
  1. http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CyclicBarrier.html
复制代码
多线程计划过程当中,常常会碰到必要守候别的线程停止今后再做其他事变的情形,好比多线程下载文件,每一个线程城市下载文件的一部分,在一切线程停止今后,必要将各部分再次拼接成一个完全的文件。
有几种计划:
1.在主线程中设置一自界说全局计数标记,在事情线程完成时,计数减一。主线程侦测该标记是不是为0,一旦为0,暗示一切事情线程已完成。
2.利用Java尺度的类CountDownLatch来完成这项事情,道理是一样的,计数。
CountDownLatch
CountDownLatch初始化设置count,即守候(await)count个线程或一个线程count次计数,经由过程事情线程来countDown计数减一,直到计数为0,await堵塞停止。
设置的count不成变动,如必要静态设置计数的线程数,可使用CyclicBarrier.
上面的例子,一切的事情线程中筹办停当今后,并非间接运转,而是守候主线程的旌旗灯号后再实行详细的操纵。

  • packagecom.example.multithread;

  • importjava.util.concurrent.CountDownLatch;

  • classDriver
  • {
  • privatestaticfinalintTOTAL_THREADS=10;
  • privatefinalCountDownLatchmStartSignal=newCountDownLatch(1);
  • privatefinalCountDownLatchmDoneSignal=newCountDownLatch(TOTAL_THREADS);

  • voidmain()
  • {
  • for(inti=0;i<TOTAL_THREADS;i++)
  • {
  • newThread(newWorker(mStartSignal,mDoneSignal,i)).start();
  • }
  • System.out.println("MainThreadNow:"+System.currentTimeMillis());
  • doPrepareWork();//筹办事情
  • mStartSignal.countDown();//计数减一为0,事情线程真正启动详细操纵
  • doSomethingElse();//做点本人的事变
  • try
  • {
  • mDoneSignal.await();//守候一切事情线程停止
  • }
  • catch(InterruptedExceptione)
  • {
  • //TODOAuto-generatedcatchblock
  • e.printStackTrace();
  • }
  • System.out.println("Allworkershavefinishednow.");
  • System.out.println("MainThreadNow:"+System.currentTimeMillis());
  • }

  • voiddoPrepareWork()
  • {
  • System.out.println("Ready,GO!");
  • }

  • voiddoSomethingElse()
  • {
  • for(inti=0;i<100000;i++)
  • {
  • ;//delay
  • }
  • System.out.println("MainThreadDosomethingelse.");
  • }
  • }

  • classWorkerimplementsRunnable
  • {
  • privatefinalCountDownLatchmStartSignal;
  • privatefinalCountDownLatchmDoneSignal;
  • privatefinalintmThreadIndex;

  • Worker(finalCountDownLatchstartSignal,finalCountDownLatchdoneSignal,
  • finalintthreadIndex)
  • {
  • this.mDoneSignal=doneSignal;
  • this.mStartSignal=startSignal;
  • this.mThreadIndex=threadIndex;
  • }

  • @Override
  • publicvoidrun()
  • {
  • //TODOAuto-generatedmethodstub
  • try
  • {
  • mStartSignal.await();//堵塞,守候mStartSignal计数为0运转前面的代码
  • //一切的事情线程都在守候统一个启动的命令
  • doWork();//详细操纵
  • System.out.println("Thread"+mThreadIndex+"DoneNow:"
  • +System.currentTimeMillis());
  • mDoneSignal.countDown();//完成今后计数减一
  • }
  • catch(InterruptedExceptione)
  • {
  • //TODOAuto-generatedcatchblock
  • e.printStackTrace();
  • }
  • }

  • publicvoiddoWork()
  • {
  • for(inti=0;i<1000000;i++)
  • {
  • ;//耗时操纵
  • }
  • System.out.println("Thread"+mThreadIndex+":dowork");
  • }
  • }

  • publicclassCountDownLatchTest
  • {
  • publicstaticvoidmain(String[]args)
  • {
  • //TODOAuto-generatedmethodstub
  • newDriver().main();
  • }

  • }
经由过程Executor启动线程:

  • classCountDownLatchDriver2
  • {
  • privatestaticfinalintTOTAL_THREADS=10;


  • privatefinalCountDownLatchmDoneSignal=newCountDownLatch(TOTAL_THREADS);



  • voidmain()
  • {
  • System.out.println("MainThreadNow:"+System.currentTimeMillis());
  • doPrepareWork();//筹办事情

  • Executorexecutor=Executors.newFixedThreadPool(TOTAL_THREADS);
  • for(inti=0;i<TOTAL_THREADS;i++)
  • {
  • //经由过程内建的线程池保护创立的线程
  • executor.execute(newRunnableWorker(mDoneSignal,i));
  • }
  • doSomethingElse();//做点本人的事变
  • try
  • {
  • mDoneSignal.await();//守候一切事情线程停止
  • }
  • catch(InterruptedExceptione)
  • {
  • //TODOAuto-generatedcatchblock
  • e.printStackTrace();
  • }
  • System.out.println("Allworkershavefinishednow.");
  • System.out.println("MainThreadNow:"+System.currentTimeMillis());
  • }

  • voiddoPrepareWork()
  • {
  • System.out.println("Ready,GO!");
  • }

  • voiddoSomethingElse()
  • {
  • for(inti=0;i<100000;i++)
  • {
  • ;//delay
  • }
  • System.out.println("MainThreadDosomethingelse.");
  • }
  • }

  • classRunnableWorkerimplementsRunnable
  • {

  • privatefinalCountDownLatchmDoneSignal;
  • privatefinalintmThreadIndex;

  • RunnableWorker(finalCountDownLatchdoneSignal,finalintthreadIndex)
  • {
  • this.mDoneSignal=doneSignal;
  • this.mThreadIndex=threadIndex;
  • }

  • @Override
  • publicvoidrun()
  • {
  • //TODOAuto-generatedmethodstub

  • doWork();//详细操纵
  • System.out.println("Thread"+mThreadIndex+"DoneNow:"
  • +System.currentTimeMillis());
  • mDoneSignal.countDown();//完成今后计数减一
  • //计数为0时,主线程打仗堵塞,持续实行其他义务
  • try
  • {
  • //能够持续做点其他的事变,与主线程有关了
  • Thread.sleep(5000);
  • System.out.println("Thread"+mThreadIndex
  • +"Dosomethingelseafternotifingmainthread");

  • }
  • catch(InterruptedExceptione)
  • {
  • //TODOAuto-generatedcatchblock
  • e.printStackTrace();
  • }

  • }

  • publicvoiddoWork()
  • {
  • for(inti=0;i<1000000;i++)
  • {
  • ;//耗时操纵
  • }
  • System.out.println("Thread"+mThreadIndex+":dowork");
  • }
  • }
输入:
  1. MainThreadNow:1359959480786Ready,GO!Thread0:doworkThread0DoneNow:1359959480808Thread1:doworkThread1DoneNow:1359959480811Thread2:doworkThread2DoneNow:1359959480813MainThreadDosomethingelse.Thread3:doworkThread3DoneNow:1359959480825Thread5:doworkThread5DoneNow:1359959480827Thread7:doworkThread7DoneNow:1359959480829Thread9:doworkThread9DoneNow:1359959480831Thread4:doworkThread4DoneNow:1359959480833Thread6:doworkThread6DoneNow:1359959480835Thread8:doworkThread8DoneNow:1359959480837Allworkershavefinishednow.MainThreadNow:1359959480838Thread0DosomethingelseafternotifingmainthreadThread1DosomethingelseafternotifingmainthreadThread2DosomethingelseafternotifingmainthreadThread3DosomethingelseafternotifingmainthreadThread9DosomethingelseafternotifingmainthreadThread7DosomethingelseafternotifingmainthreadThread5DosomethingelseafternotifingmainthreadThread4DosomethingelseafternotifingmainthreadThread6DosomethingelseafternotifingmainthreadThread8Dosomethingelseafternotifingmainthread
复制代码
  1. CyclicBarrier
复制代码
  1. 利用CyclickBarrier的例子:
复制代码

  • classWalkTarget
  • {
  • privatefinalintmCount=5;


  • privatefinalCyclicBarriermBarrier;


  • ExecutorServicemExecutor;

  • classBarrierActionimplementsRunnable


  • {
  • @Override


  • publicvoidrun()


  • {
  • //TODOAuto-generatedmethodstub


  • System.out.println("一切线程都已完成义务,计数到达预设值");


  • //mBarrier.reset();//恢复到初始化形态



  • }
  • }

  • WalkTarget()
  • {
  • //初始化CyclicBarrier


  • mBarrier=newCyclicBarrier(mCount,newBarrierAction());


  • mExecutor=Executors.newFixedThreadPool(mCount);

  • for(inti=0;i<mCount;i++)


  • {
  • //启开工作线程


  • mExecutor.execute(newWalker(mBarrier,i));


  • }
  • }
  • }

  • //事情线程


  • classWalkerimplementsRunnable


  • {
  • privatefinalCyclicBarriermBarrier;


  • privatefinalintmThreadIndex;



  • Walker(finalCyclicBarrierbarrier,finalintthreadIndex)


  • {
  • mBarrier=barrier;
  • mThreadIndex=threadIndex;
  • }

  • @Override
  • publicvoidrun()
  • {
  • //TODOAuto-generatedmethodstub
  • System.out.println("Thread"+mThreadIndex+"isrunning...");
  • //实行义务
  • try
  • {
  • TimeUnit.MILLISECONDS.sleep(5000);
  • //dotask
  • }
  • catch(InterruptedExceptione)
  • {
  • //TODOAuto-generatedcatchblock
  • e.printStackTrace();
  • }

  • //完成义务今后,守候其他线程完成义务
  • try
  • {
  • mBarrier.await();
  • }
  • catch(InterruptedExceptione)
  • {
  • //TODOAuto-generatedcatchblock
  • e.printStackTrace();
  • }
  • catch(BrokenBarrierExceptione)
  • {
  • //TODOAuto-generatedcatchblock
  • e.printStackTrace();
  • }
  • //其他线程义务都完成今后,堵塞排除,能够持续接上去的义务
  • System.out.println("Thread"+mThreadIndex+"dosomethingelse");
  • }

  • }

  • publicclassCountDownLatchTest
  • {
  • publicstaticvoidmain(String[]args)
  • {
  • //TODOAuto-generatedmethodstub
  • //newCountDownLatchDriver2().main();
  • newWalkTarget();
  • }

  • }
输入(注重,只要一切的线程barrier.await以后才干持续实行其他的操纵):
  1. Thread0isrunning...Thread2isrunning...Thread3isrunning...Thread1isrunning...Thread4isrunning...一切线程都已完成义务,计数到达预设值Thread4dosomethingelseThread0dosomethingelseThread2dosomethingelseThread3dosomethingelseThread1dosomethingelse
复制代码
CountDownLatch和CyclicBarrier复杂对照:
<p>CountDownLatch
CyclicBarrier
软件包
java.util.concurrent
java.util.concurrent
合用情形
主线程守候多个事情线程停止
多个线程之间相互守候,直到一切线程到达一个停滞点(Barrierpoint)
次要办法
CountDownLatch(intcount)(主线程挪用)
初始化计数
CountDownLatch.await(主线程挪用)
堵塞,直到守候计数为0排除堵塞
CountDownLatch.countDown

Java的B/s开发是通常是javaweb开发,又叫J2EE开发,J2SE是手机开发。C#的C/s和B/s开发是说.net网页编程和Asp开发。。u在这里说明一点;资深一点的Java和C#程序员都明白一点
若天明 该用户已被删除
沙发
发表于 2015-1-19 20:41:04 | 只看该作者
其实说这种话的人就如当年小日本号称“三个月拿下中国”一样大言不惭。不是Tomjava泼你冷水,你现在只是学到了Java的骨架,却还没有学到Java的精髓。接下来你得研究设计模式了。
冷月葬花魂 该用户已被删除
板凳
发表于 2015-1-24 16:19:20 | 只看该作者
Pet Store.(宠物店)是SUN公司为了演示其J2EE编程规范而推出的开放源码的程序,应该很具有权威性,想学J2EE和EJB的朋友不要 错过了。
飘飘悠悠 该用户已被删除
地板
发表于 2015-1-25 22:41:02 | 只看该作者
是一种语言,用以产生「小应用程序(Applet(s))
第二个灵魂 该用户已被删除
5#
发表于 2015-1-27 20:07:16 | 只看该作者
是一种语言,用以产生「小应用程序(Applet(s))
柔情似水 该用户已被删除
6#
发表于 2015-2-5 09:14:20 | 只看该作者
你现在最缺的是实际的工作经验,而不是书本上那些凭空想出来的程序。
兰色精灵 该用户已被删除
7#
发表于 2015-2-11 08:21:04 | 只看该作者
象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。
愤怒的大鸟 该用户已被删除
8#
发表于 2015-3-1 09:03:37 | 只看该作者
至于JDBC,就不用我多说了,你如果用java编过存取数据库的程序,就应该很熟悉。还有,如果你要用Java编发送电子邮件的程序,你就得看看Javamail 了。
飘灵儿 该用户已被删除
9#
发表于 2015-3-2 08:46:14 | 只看该作者
还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。
若相依 该用户已被删除
10#
发表于 2015-3-11 02:39:12 | 只看该作者
象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。
海妖 该用户已被删除
11#
发表于 2015-3-17 19:09:37 | 只看该作者
是一种语言,用以产生「小应用程序(Applet(s))
因胸联盟 该用户已被删除
12#
发表于 2015-3-24 20:36:30 | 只看该作者
学Java必读的两个开源程序就是Jive和Pet Store.。 Jive是国外一个非常著名的BBS程序,完全开放源码。论坛的设计采用了很多先进的技术,如Cache、用户认证、Filter、XML等,而且论坛完全屏蔽了对数据库的访问,可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序,这是我们平时编程时容易忽略的一部份(中国程序员一般只注重编程的技术含量,却完全不考虑用户的感受,这就是我们与国外软件的差距所在)。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-9-23 01:41

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表