简单生活 发表于 2015-1-18 11:23:42

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

恰恰证明了java的简单,要不怎么没有通过c/c++来搞个这种框架?本文次要是参考官方文档做一进修用处。
官方链接:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CountDownLatch.htmlhttp://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");
[*]}
[*]}
输入:
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:1359959480838Thread0DosomethingelseafternotifingmainthreadThread1DosomethingelseafternotifingmainthreadThread2DosomethingelseafternotifingmainthreadThread3DosomethingelseafternotifingmainthreadThread9DosomethingelseafternotifingmainthreadThread7DosomethingelseafternotifingmainthreadThread5DosomethingelseafternotifingmainthreadThread4DosomethingelseafternotifingmainthreadThread6DosomethingelseafternotifingmainthreadThread8DosomethingelseafternotifingmainthreadCyclicBarrier利用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以后才干持续实行其他的操纵):
Thread0isrunning...Thread2isrunning...Thread3isrunning...Thread1isrunning...Thread4isrunning...一切线程都已完成义务,计数到达预设值Thread4dosomethingelseThread0dosomethingelseThread2dosomethingelseThread3dosomethingelseThread1dosomethingelseCountDownLatch和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))

第二个灵魂 发表于 2015-1-27 20:07:16

是一种语言,用以产生「小应用程序(Applet(s))

柔情似水 发表于 2015-2-5 09:14:20

你现在最缺的是实际的工作经验,而不是书本上那些凭空想出来的程序。

兰色精灵 发表于 2015-2-11 08:21:04

象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。

愤怒的大鸟 发表于 2015-3-1 09:03:37

至于JDBC,就不用我多说了,你如果用java编过存取数据库的程序,就应该很熟悉。还有,如果你要用Java编发送电子邮件的程序,你就得看看Javamail 了。

飘灵儿 发表于 2015-3-2 08:46:14

还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。

若相依 发表于 2015-3-11 02:39:12

象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。

海妖 发表于 2015-3-17 19:09:37

是一种语言,用以产生「小应用程序(Applet(s))

因胸联盟 发表于 2015-3-24 20:36:30

学Java必读的两个开源程序就是Jive和Pet Store.。 Jive是国外一个非常著名的BBS程序,完全开放源码。论坛的设计采用了很多先进的技术,如Cache、用户认证、Filter、XML等,而且论坛完全屏蔽了对数据库的访问,可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序,这是我们平时编程时容易忽略的一部份(中国程序员一般只注重编程的技术含量,却完全不考虑用户的感受,这就是我们与国外软件的差距所在)。
页: [1]
查看完整版本: JAVA网站制作之Java:多线程守候一切线程停止(CountDownLatch/CyclicBarrier) .仓酷云