1. 程式人生 > >多線程設計模式:第六篇 - ThreadLocal和Active Object模式

多線程設計模式:第六篇 - ThreadLocal和Active Object模式

note active 計算 news 設計模式 簡化 Language return 通過

一,ThreadLocal

Java 中的 ThreadLocal 類給多線程編程提供了一種可以讓每個線程具有自己獨立空間的機制,在這個空間內存儲的數據是線程特有的,不對外共享。

ThreadLocal 類提供了 set() 和 get() 方法用於設置和獲取線程特有數據,且 ThreadLocal 支持泛型,這樣可以通過參數來指定要存儲數據的類型。

二,Active Object模式

Active Object模式的主要目的是實現方法調用和執行分離到不同的線程中,這樣可以提高調用方的響應速度,同時執行方的執行策略對調用方透明,達到雙方互不幹擾。這和之前我們說的生產者-消費者模式,Worker-Thread模式非常相似。

下面的程序示例,我們選擇使用 juc 包中的 Executor 框架來實現一個Active Object模式:

/**
 * @author koma <[email protected]>
 * @date 2018-11-05
 */
public class Main {
    public static void main(String[] args) {
        ActiveObject activeObject = ActiveObjectFactory.createActiveObject();
        try {
            new MakerClientThread("Alice", activeObject).start();
            new MakerClientThread("Bobby", activeObject).start();
            Thread.sleep(5000);
        } catch (RejectedExecutionException e) {
        } catch (InterruptedException e) {
        } finally {
            activeObject.shutdown();
        }
    }
}

public interface ActiveObject {
    public abstract Future<String> makeString(int count, char fillchar);
    public abstract void displayString(String s);
    public abstract void shutdown();
}

public class ActiveObjectFactory {
    public static ActiveObject createActiveObject() {
        return new ActiveObjectImpl();
    }
}

public class ActiveObjectImpl implements ActiveObject {
    private final ExecutorService executorService = Executors.newSingleThreadExecutor();

    @Override
    public Future<String> makeString(final int count, final char fillchar) {
        class MakeStringRequest implements Callable<String> {
            @Override
            public String call() throws Exception { //請求的執行在另外一個線程中異步執行
                char[] buffer = new char[count];
                for (int i = 0; i < count; i++) {
                    buffer[i] = fillchar;
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                return new String(buffer);
            }
        }
        return executorService.submit(new MakeStringRequest()); //提交請求並馬上返回
    }

    @Override
    public void shutdown() {
        executorService.shutdown();
    }
}

public class MakerClientThread extends Thread {
    private final ActiveObject activeObject;
    private final char fillchar;

    public MakerClientThread(String name, ActiveObject activeObject) {
        super(name);
        this.activeObject = activeObject;
        this.fillchar = name.charAt(0);
    }

    @Override
    public void run() {
        try {
            for (int i = 0; true; i++) {
                //使用 Future 模式獲取數據
                Future<String> future = activeObject.makeString(i, fillchar);
                Thread.sleep(100);
                String value = future.get();
                System.out.println(Thread.currentThread().getName()+": value = "+value);
            }
        } catch (InterruptedException e) {
        } catch (ExecutionException e) {
        }
    }
}

1,關於 Active Object模式 的說明

Active Object模式揭示了一個事實即如果可以把方法調用和執行分到不同的線程,即跨越線程界線執行,那麽就可以跨越計算機執行,即透過網絡在遠端計算機上執行方法。與該模式相關的 Java 技術叫 RMI。

2,POSA2 中的主動對象(Active Object)設計模式定義

主動對象(Active Object)設計模式將方法執行和調用分離,加強並發和簡化對駐留在自身控制線程中對象的同步訪問。

主動對象 別名 並發對象(Concurrent Object)

多線程設計模式:第六篇 - ThreadLocal和Active Object模式