当前位置:编程学习 > JAVA >>

Java分布式应用学习笔记05多线程下的并发同步器----前篇

 

1.  前言

JDK提供的并发包,除了上一篇提到的用于集合外,还有线程的调度、协作、调度等等功能。上篇提到过,线程之间除了竞争关系,还有协作关系。在高并发环境下有效利用Java并发包解决线程之间协作的特殊场景。在并行计算,尤其是多线程计算的结果集合并的时候都需要用到这些并发同步器。还有一种使用场景,就是跨越多台机器(实机)的多线程进行并行运算,需要将多台机器进行结果集的汇总,合并。其原理核心也是使用这些并发协作包。

2.  FutureTask

FutureTask是进行并行结果集合并的类,此类是Future接口的实现。在主线程中启动多个线程进行并发计算,之后再根据各个线程的执行结果进行汇总,归并,得出一个总的结果,这个多线程可以是在一台机器上,充分利用多核CPU硬件,在科研单位可能分布式集群环境一起并发计算一个大任务,每个机器相当于一个线程,执行完毕后将反馈的结果返回来进行合并后才是最终的结果。而主线程可以等待分线程的结果,也可以不等待,全凭具体业务需要而定,不过一般情况下还是要等一等分线程的结果才能往下执行的。如果不等分线程,也可以在主线程中不再理会分线程即可。

举个实例,比如这时候东方不败要想练成《葵花宝典》,那么需要前提条件是2个,第一手中得有《葵花宝典》秘籍,第二就是挥刀自宫。恩,挥刀自宫这个主线程——东方不败可以自己完成,夺取《葵花宝典》可以派别人——兄弟童柏雄去干,2条线并行实施,等另一个人取得《葵花宝典》了,这边主线程也挥刀自宫了,行了,能练了!

咱先看代码行吧

Java代码 

<span style="font-size: small;">package threadConcurrent.test; 

 

import java.util.concurrent.Callable; 

import java.util.concurrent.ExecutionException; 

import java.util.concurrent.FutureTask; 

 

/**

 * 分线程汇总

 * @author liuyan

 */ 

public class FutureTaskDemo { 

 

    @SuppressWarnings("unchecked") 

    public static void main(String[] args) { 

 

        // 初始化一个Callable对象和FutureTask对象 

        Callable otherPerson = new OtherPerson(); 

 

        // 由此任务去执行 

        FutureTask futureTask = new FutureTask(otherPerson); 

 

        // 使用futureTask创建一个线程 

        Thread newhread = new Thread(futureTask); 

         

        System.out.println("newhread线程现在开始启动,启动时间为:" + System.nanoTime() 

                + " 纳秒"); 

         

        newhread.start(); 

         

        System.out.println("主线程——东方不败,开始执行其他任务"); 

         

        System.out.println("东方不败开始准备小刀,消毒..."); 

 

        //兄弟线程在后台的计算线程是否完成,如果未完成则等待 

        //阻塞 

        while (!futureTask.isDone()) { 

             

            try { 

                Thread.sleep(500); 

                System.out.println("东方不败:“等兄弟回来了,我就和小弟弟告别……颤抖……”"); 

            } catch (InterruptedException e) { 

                e.printStackTrace(); 

            }  

        } 

         

        System.out.println("newhread线程执行完毕,此时时间为" + System.nanoTime()); 

        String result = null; 

        try { 

            result = (String) futureTask.get(); 

 

        } catch (InterruptedException e) { 

            e.printStackTrace(); 

        } catch (ExecutionException e) { 

            e.printStackTrace(); 

        } 

         

        if("OtherPerson:::经过一番厮杀取得《葵花宝典》".equals(result)){ 

            System.out.println("兄弟,干得好,我挥刀自宫了啊!"); 

        }else{ 

            System.out.println("还好我没自宫!否则白白牺牲了……"); 

        } 

         

    } 

 

@SuppressWarnings("all") 

class OtherPerson implements Callable { 

 

    @Override 

    public Object call() throws Exception { 

 

        // 先休息休息再拼命去! 

        Thread.sleep(5000); 

        String result = "OtherPerson:::经过一番厮杀取得《葵花宝典》"; 

        System.out.println(result); 

        return result; 

    } 

 

}</span> 

 在这个例子中主线程代表东方不败,分线程代表兄弟——童柏雄,主线程派出FutureTask,把它放置于一个线程对象中,之后线程开始启动,分支线程开始工作。主线程也没闲着,继续做自己的事情,消毒,做着心理斗争等等,通过一个阻塞的死循环,等待分线程的状态,调用分线程的futureTask.isDone()方法进行判断,看看兄弟是否执行结束了,结束了通过futureTask.get()将分线程的执行结果取出来,结果出来了,主线程根据分线程的执行结果再做决定。执行后,结果大家都明了。有一点需要说明的是,有可能分线程与主线程的执行不在一台物理机器上,分线程可以使用jms、webservic、rmi甚至socket技术请求远程的类为其服务。分线程根据远程返回的结果再返回给本机器的主线程,之后再做决策。分布式计算的核心原理也是如此,当然分布式计算比这个复杂得多,笔者只是说其核心的实现原理。

3.  Semaphore

Semaphore是限制多线程共享资源的一个东东,多线程并发访问一个资源

补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,