Java多线程设计模式(5)Future模式

一 Future Pattern

   假如有一个执行起来需要花费一些时间的方法,为了省去不必要的等待执行结果出来,继续做别的事情,则可以事先获取一个“提货单”即Future参与者,Future Pattern模式也就是这样的方式,当一个线程需要另一个线程的处理的结果时候,则不必一直等着处理结果,可以先处理别的事情,提前拿个Future对象,再过一段时间来获取另一个线程的处理结果

   在多个线程中,返回另一个线程的执行结果,最简单的就是采用主线程调用子线程后,一直无限循环等待子线程处理结果。由于这种会浪费等待的时间,且会浪费CPU,在此基础上,进而在子线程中调用主线程的方法来实现。可以利用静态方法和实例方法,在利用实例方法中就需要在调用子线程的时候通过构造器将主线程对象的实例传递给子线程使用。但是这种方式还欠缺一些灵活性,主线程的方法是由子线程调用的,至于什么时候该方法被调用则不清楚,不利于主线程处理。

    为了改变这种模式,则就利用Future Pattern,主线程调用子线程后,继续执行程序,只是在调用子线程后,暂时获取一个临时对象Future,这样在主线程想获取Future内部数据的时候,就可以调用Future的方法,如果该方法中已经有了处理结果,则此时就可以立刻获取,如果没有则主线程就需要稍微等一下返回结果。这种方式的优点就是主线程可以任何时候调用返回的结果,主线程不必长等待返回的结果。

  Future Pattern的参与者

  1 Client参与者,发送请求方,调用子线程的,它一旦发送请求后,就获取一个VirtualData,作为请求的结果。

  2 Host参与者,接受请求者,会为请求者返回一个FutureData对象。并且会启动一个线程来执行真正的任务,最后将任务的返回结果RealData对象赋值给FutureData对象。

   3 VirturalData参与者,用来统一代表FutureData参与者与RealData参与者,是他们的统一接口。

   4 FutureData参与者,它是当做工作还没有正式完成前的临时代表,会在其中进行线程的等待,唤醒,以及提供Client参与者调用处理结果的方法。

   5 RealData参与者,具体真正进行操作数据的类。

实例代码:

主要是FutureData类和Host参与者以及Client参与者,ReaLData就是真正执行的任务没写。

Client参与者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package whut.future;
public class FutureMain {
    public static void main(String[] args) {
     // TODO Auto-generated method stub
     System.out.println("main BEGIN");
     Host host=new Host();
     Data data1=host.request(10'A');
     Data data2=host.request(20'B');
                    
     System.out.println("main otherJob BEGIN");
     try{
         Thread.sleep(2000);
     }catch(InterruptedException e){
     }
     System.out.println("main otherJob END");
                    
     System.out.println("data1="+data1.getContent());
     System.out.println("data2="+data2.getContent());
     System.out.println("main END");
    }
}

Host参与者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package whut.future;
public class Host {
    //使用Thread-Per-Messagee Pattern
    public Data request(final int count,final char c)
    {
        System.out.println(" request("+count+","+c+") BEGIN");
        final FutureData future=new FutureData();
        //启动线程执行
        new Thread()
        {
            public void run()
            {
                RealData realData=new RealData(count,c);
                future.setRealData(realData);
            }
        }.start();
        System.out.println(" request("+count+","+c+") END");
        return future;
    }
}


FutureData参与者,这个是真正的关键部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package whut.future;
//核心部分
public class FutureData implements Data {
    private RealData realData = null;
    private boolean ready = false;
    public synchronized void setRealData(RealData realData) {
        if (ready)
            return;// 利用Balk Pattern来防止赋值多次
        this.realData = realData;
        this.ready = true;
        notifyAll();
    }
    public synchronized String getContent() {
        // 运用了Guarded Suspension Pattern
        while (!ready) {
            try {
                wait();
            catch (InterruptedException e) {
            }
        }
        return realData.getContent();
    }
}


上一篇:spring cloud(学习笔记)微服务启动错误(1)


下一篇:Qt5多线程/线程池技术集锦(1)