其他多線程設計模式

觀察者設計模式觀察線程的生命週期

//使用觀察者設計模式觀察線程的生命週期   被觀察者是Thread
public abstract class ObservableRunnable implements Runnable {

    final protected LifeCycleListener listener; //觀察者

    public ObservableRunnable(final LifeCycleListener listener) {
        this.listener = listener;
    }

    protected void notifyChange(final RunnableEvent event) {
        listener.onEvent(event);
    }

    public enum RunnableState {
        RUNNING, ERROR, DONE
    }

    public static class RunnableEvent {
        private final RunnableState state;
        private final Thread thread;//哪個線程
        private final Throwable cause;//失敗的原因

        public RunnableEvent(RunnableState state, Thread thread, Throwable cause) {
            this.state = state;
            this.thread = thread;
            this.cause = cause;
        }

        public RunnableState getState() {
            return state;
        }

        public Thread getThread() {
            return thread;
        }

        public Throwable getCause() {
            return cause;
        }
    }
}

public interface LifeCycleListener {//觀察者
    void onEvent(ObservableRunnable.RunnableEvent event);
}

public class ThreadLifeCycleObserver implements LifeCycleListener {

    private final Object LOCK = new Object();//共享數據的問題

    public void concurrentQuery(List<String> ids) {
        if (ids == null || ids.isEmpty())
            return;
             //把自己作爲observer給你
        ids.stream().forEach(id -> new Thread(new ObservableRunnable(this) {
            @Override
            public void run() {
                try {
                    notifyChange(new RunnableEvent
                    (RunnableState.RUNNING, Thread.currentThread(), null));
                    System.out.println("query for the id " + id);
                    Thread.sleep(1000L);
//                    int i = 1/0;
                    notifyChange
                    (new RunnableEvent(RunnableState.DONE, Thread.currentThread(), null));
                } catch (Exception e) {
                    notifyChange
                    (new RunnableEvent(RunnableState.ERROR, Thread.currentThread(), e));
                }
            }
        }, id).start());
    }
    @Override
    public void onEvent(ObservableRunnable.RunnableEvent event) {
        //把當前對象傳給ObservableRunnable,可能有多線程訪問問題
        synchronized (LOCK) {//數據不一致,線程安全問題
            System.out.println("The runnable [" + event.getThread().getName() + "] 
            data changed and state is [" + event.getState() + "]");
            if (event.getCause() != null) {
                //如果失敗 了可能再去嘗試等操作
                System.out.println("The runnable [" + event.getThread().getName() + 
                "] process failed.");
                event.getCause().printStackTrace();
            }
        }
    }
}

public class ThreadLifeCycleClient {
    public static void main(String[] args) {
        //啓動2個線程去幹活
        new ThreadLifeCycleObserver().concurrentQuery(Arrays.asList("1", "2"));
    }
}

單線程執行設計模式,有一個門,始終只能一個人通過

public class Client {
    public static void main(String[] args) {
        Gate gate = new Gate();
        User bj = new User("Baobao", "Beijing", gate);
        User sh = new User("ShangLao", "ShangHai", gate);
        User gz = new User("GuangLao", "GuangZhou", gate);

        bj.start();
        sh.start();
        gz.start();
    }
}

/**
 * SharedResource共享資源
 */
public class Gate {//記錄一個大門(臨界值)的用戶信息,這裏沒有對門進行加鎖的方式實現的
    private int counter = 0;
    private String name = "Nobody";
    private String address = "Nowhere";

    /**
     * 臨界值
     *
     * @param name
     * @param address
     */
    public synchronized void pass(String name, String address) {
        this.counter++;
        /*race*/
        this.name = name;
        this.address = address;
        verify();
    }

    private void verify() {
        //每次只有一個人通過
        if (this.name.charAt(0) != this.address.charAt(0)) {
            System.out.println("*******BROKEN********" + toString());
        }
    }

    public synchronized String toString() {
        return "No." + counter + ":" + name + "," + address;
    }
}

public class User extends Thread {//有一個門,始終有一個人通過的場景

    private final String myName;

    private final String myAddress;

    private final Gate gate;

    public User(String myName, String myAddress, Gate gate) {
        this.myName = myName;
        this.myAddress = myAddress;
        this.gate = gate;
    }

    @Override
    public void run() {
        System.out.println(myName + " BEGIN");
        while (true) {
            this.gate.pass(myName, myAddress);
        }
    }
}

多線程讀寫鎖分離設計模式

/**
 * ReadWriteLock design pattern
 * Reader-Writer design pattern
 */
public class ReadWritLockClient {
    public static void main(String[] args) {
        final SharedData sharedData = new SharedData(10);
        new ReaderWorker(sharedData).start();
        new ReaderWorker(sharedData).start();
        new ReaderWorker(sharedData).start();
        new ReaderWorker(sharedData).start();
        new ReaderWorker(sharedData).start();
        new WriterWorker(sharedData, "qwertyuiopasdfg").start();
        new WriterWorker(sharedData, "QWERTYUIOPASDFG").start();
    }
}

public  class SharedData {

    private final char[] buffer;

    private final  ReadWriteLock lock = new ReadWriteLock();

    public SharedData(int  size) {
        this.buffer = new char[size];
        for (int i = 0; i < size; i++) {
            this.buffer[i] = '*';
        }
    }

    public char[] read() throws InterruptedException {
        try {
            lock.readLock();
            return this.doRead();
        } finally {
            lock.readUnlock();
        }
    }

    public void write(char c) throws InterruptedException {
        try {
            lock.writeLock();
            this.doWrite(c);
        } finally {
            lock.writeUnlock();
        }
    }

    private void doWrite(char c) {
        for (int i = 0; i < buffer.length; i++) {
            buffer[i] = c;
            slowly(10);
        }
    }

    private char[] doRead() {
        char[] newBuf = new char[buffer.length];
        for (int i = 0; i < buffer.length; i++)
            newBuf[i] = buffer[i];

        slowly(50);
        return newBuf;
    }

    private void slowly(int ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
        }
    }
}

public class ReadWriteLock {
    private int readingReaders = 0;
    private int waitingReaders = 0;
    private int writingWriters = 0;
    private int waitingWriters = 0;
    //實現寫鎖優先
    private boolean preferWriter = true;

    public ReadWriteLock() {
        this(true);
    }

    public ReadWriteLock(boolean preferWriter) {
        this.preferWriter = preferWriter;
    }

    //獲取對象的鎖,這裏用了try finally   同時用鎖的時候也是要try finally的
    public synchronized void readLock() throws InterruptedException {
        this.waitingReaders++;
        try {
            while (writingWriters > 0 || (preferWriter && waitingWriters > 0)) {
                this.wait();
            }
            this.readingReaders++;
        } finally {
            this.waitingReaders--;
        }

    }

    public synchronized void readUnlock() {
        this.readingReaders--;
        this.notifyAll();
    }

    public synchronized void writeLock() throws InterruptedException {
        this.waitingWriters++;
        try {
            while (readingReaders > 0 || writingWriters > 0) {
                this.wait();
            }
            this.writingWriters++;
        } finally {
            this.waitingWriters--;
        }
    }

    public synchronized void writeUnlock() {
        this.writingWriters--;
        this.notifyAll();
    }
}

public class ReaderWorker extends Thread {

    private final SharedData data;

    public ReaderWorker(SharedData data) {
        this.data = data;
    }

    @Override
    public void run() {
        try {
            while (true) {
                char[] readBuf = data.read();
                System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(readBuf));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class WriterWorker extends Thread {

    private static final Random random = new Random(System.currentTimeMillis());

    private final SharedData data;

    private final String filler;

    private int index = 0;

    public WriterWorker(SharedData data, String filler) {
        this.data = data;
        this.filler = filler;
    }

    @Override
    public void run() {
        try {
            while (true) {
                char c = nextChar();
                data.write(c);
                Thread.sleep(random.nextInt(1000));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private char nextChar() {
        char c = filler.charAt(index);
        index++;
        if (index >= filler.length())
            index = 0;
        return c;
    }
}

多線程 Future 設計模式

public interface FutureTask<T> {

    T call();
}

/**   想想UML類圖
 * Future        ->  代表的是未來的一個憑據
 * FutureTask    ->  將你的調用邏輯進行了隔離
 * FutureService ->  橋接 Future和 FutureTask
 */
public class SyncInvoker {

    public static void main(String[] args) throws InterruptedException {
        /*String result = get();//同步調用
        System.out.println(result);*/

        //思路:返回的Future,具體類AsynFuture,任務FutureTask,將他們橋接起來的FutureService  畫出uml圖分析一下
        FutureService futureService = new FutureService();
        Future<String> future = futureService.submit(() -> {
            try {
                Thread.sleep(10000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "FINISH";
        }, System.out::println);

        //這裏沒阻塞
        System.out.println("===========");
        System.out.println(" do other thing.");
        Thread.sleep(1000);
        System.out.println("===========");

//        //這裏阻塞了
//        String result = future.get();
//        System.out.println(result);
    }

    private static String get()
            throws InterruptedException {
        Thread.sleep(10000l);
        return "FINISH";
    }
}

public class FutureService {//將Future和FutureTask橋接起來

    public <T> Future<T> submit(final FutureTask<T> task) {
        //異步的Future實現 ,調用asynFuture的方法可能是不一樣的線程
        AsynFuture<T> asynFuture = new AsynFuture<>();
        new Thread(() -> {
            T result = task.call();
            asynFuture.done(result);
        }).start();
        return asynFuture;
    }

    //執行完後就Consumer
    public <T> Future<T> submit(final FutureTask<T> task, final Consumer<T> consumer) {
        AsynFuture<T> asynFuture = new AsynFuture<>();
        new Thread(() -> {
            T result = task.call();
            asynFuture.done(result);
            //執行後就立馬通知了,減少時間誤差
            consumer.accept(result);
        }).start();
        return asynFuture;
    }
}

public interface Future<T> {

    T get() throws InterruptedException;
}

public class AsynFuture<T> implements Future<T> {

    private volatile boolean done = false;

    private T result;

    public void done(T result) {
        synchronized (this) {
            this.result = result;
            this.done = true;
            this.notifyAll();//done和get不一定是同一個線程
        }
    }

    @Override
    public T get() throws InterruptedException {
        synchronized (this) {
            while (!done) {
                //阻塞的,考慮多線程
                this.wait();
            }
        }
        return result;
    }
}

多線程Count Down設計模式

public class CustomCountDownClient {

    private static final Random random = new Random(System.currentTimeMillis());

    public static void main(String[] args) throws InterruptedException {

        final CountDown latch = new CountDown(5);
        System.out.println("準備多線程處理任務.");
        //The first phase.

        IntStream.rangeClosed(1, 5).forEach(i ->
                new Thread(() -> {
                    System.out.println(Thread.currentThread().getName() + " is working.");
                    try {
                        Thread.sleep(random.nextInt(1000));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    latch.down();
                }, String.valueOf(i)).start()
        );

        latch.await();
        //The second phase.
        System.out.println("多線程任務全部結束,準備第二階段任務");
        System.out.println("............");
        System.out.println("FINISH");
    }
}

public class CountDown {
    private final int total;

    private int counter = 0;

    public CountDown(int total) {
        this.total = total;
    }

    public void down() {
        synchronized (this) {
            this.counter++;
            this.notifyAll();
        }
    }

    public void await() throws InterruptedException {
        synchronized (this) {
            while (counter != total) {
                this.wait();
            }
        }
    }
}

public class JDKCountDown {

    private static final Random random = new Random(System.currentTimeMillis());

    public static void main(String[] args) throws InterruptedException {

        //底層是AbstractQueuedSynchronizer實現的
        final CountDownLatch latch = new CountDownLatch(5);
        System.out.println("準備多線程處理任務.");
        //The first phase.

        IntStream.rangeClosed(1, 5).forEach(i ->
                new Thread(() -> {
                    System.out.println(Thread.currentThread().getName() + " is working.");
                    try {
                        Thread.sleep(random.nextInt(1000));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    latch.countDown();
                }, String.valueOf(i)).start()
        );

        latch.await();
        //The second phase.
        System.out.println("多線程任務全部結束,準備第二階段任務");
        System.out.println("............");
        System.out.println("FINISH");

    }
}

在這裏插入圖片描述

多線程Active Objects設計模式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章