java实现golang类似的chan

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lastsweetop/article/details/83992037

java版本的CSP操作

public class Chan<T> {
    private T message;

    private boolean empty = true;

    public synchronized T take() {
        while (empty) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        empty = true;
        notifyAll();
        return message;
    }

    public synchronized void put(T message) {
        while (!empty) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        empty = false;
        this.message = message;
        notifyAll();
    }
}

基本的csp操作上面就可以了,但是如果想实现golang的select模型,就要对消息进行改造一下:

class ChanMessage<T> {
    private String type;
    private T data;

    public ChanMessage(String type, T data) {
        this.type = type;
        this.data = data;
    }


    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }


}

public class Chan<T extends ChanMessage> {
    private T message;

    private boolean empty = true;

    public synchronized T take() {
        while (empty) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        empty = true;
        notifyAll();
        return message;
    }

    public synchronized void put(T message) {
        while (!empty) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        empty = false;
        this.message = message;
        notifyAll();
    }


    public static void main(String[] args) {

        Chan<ChanMessage<Integer>> chanMessageChan = new Chan<>();


        new Thread(() -> {
            chanMessageChan.put(new ChanMessage<>("timeout", new Integer(1)));
        }).start();


        new Thread(() -> {
            ChanMessage<Integer> chanMessage = chanMessageChan.take();
            switch (chanMessage.getType()) {
                case "timeout":
                    System.out.println(chanMessage.getData());
                    break;
                default:
                    break;

            }
        }).start();
    }
}

那么具有缓存的chan当然也好实现了

public class Chan<T extends ChanMessage> {

    private List<T> lists = new ArrayList<>();

    private int size;

    public Chan(int size) {
        this.size = size;
    }


    public synchronized T take() {
        while (lists.size() == 0) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        T message = lists.remove(0);
        notifyAll();
        return message;
    }

    public synchronized void put(T message) {
        while (lists.size() >= size) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        lists.add(message);
        notifyAll();
    }
 }

来,我们用超时退出试下chan的复用

public static void main(String[] args) {
        Chan<ChanMessage<Integer>> chanMessageChan = new Chan<>(1);

        new Thread(() -> {
            chanMessageChan.put(new ChanMessage<>("success", new Integer(1)));

            chanMessageChan.put(new ChanMessage<>("success", new Integer(2)));
        }).start();

        new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            chanMessageChan.put(new ChanMessage<>("timeout", new Integer(0)));
        }).start();
        new Thread(() -> {
            while (true) {
                ChanMessage<Integer> chanMessage = chanMessageChan.take();
                switch (chanMessage.getType()) {
                    case "success":
                        System.out.println(chanMessage.getData());
                        break;
                    case "timeout":
                        return;
                    default:
                        break;

                }
            }
        }).start();
    }

对于追求完美的人来说,不介意加点语法糖

 	static void go(Runnable runnable) {
        new Thread(runnable).start();
    }


    public static void main(String[] args) {
        Chan<ChanMessage<Integer>> chanMessageChan = new Chan<>(1);

        go(() -> {
            chanMessageChan.put(new ChanMessage<>("success", new Integer(1)));

            chanMessageChan.put(new ChanMessage<>("success", new Integer(2)));
        });

        go(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            chanMessageChan.put(new ChanMessage<>("timeout", new Integer(0)));
        });
        go(() -> {
            while (true) {
                ChanMessage<Integer> chanMessage = chanMessageChan.take();
                switch (chanMessage.getType()) {
                    case "success":
                        System.out.println(chanMessage.getData());
                        break;
                    case "timeout":
                        return;
                    default:
                        break;

                }
            }
        });
    }

至此就用java实现了golang的select操作,写完这段代码有种打通了任督二脉的感觉,语言不再是障碍

没有更多推荐了,返回首页