@@ -0,0 +1,2828 @@
+package com.github.noobymatze.concurrency;%0A%0Aimport java.util.Objects;%0Aimport java.util.function.Supplier;%0A%0A/**%0A * A Channel encapsulates the communication between two threads. It builds%0A * upon the logic implemented in a %7B@link MVar%7D.%0A *%0A * @param %3CT%3E The datatype, which can be sent over this channel.%0A */%0Apublic final class Channel%3CT%3E %7B%0A%0A    /**%0A     * References the item, that sits at the start of this%0A     * Channel.%0A     */%0A    private final MVar%3CMVar%3CItem%3CT%3E%3E%3E start;%0A%0A    /**%0A     * References the item, that sits at the end of this channel,%0A     * for easier write access.%0A     */%0A    private final MVar%3CMVar%3CItem%3CT%3E%3E%3E end;%0A%0A    /**%0A     * Creates a new Channel, referencing an empty MVar.%0A     */%0A    public Channel() %7B%0A        MVar%3CItem%3CT%3E%3E last = MVar.empty();%0A        this.start = MVar.withDefault(last);%0A        this.end = MVar.withDefault(last);%0A    %7D%0A%0A    /**%0A     * Consumes a value from this channel, thus deleting it%0A     * from it. Blocks, if there is none.%0A     * %0A     * @return The Element, that is currently at the beginning of%0A     * this Channel.%0A     * @throws InterruptedException If any thread interrupted the current one%0A     * during synchronization.%0A     */%0A    public T read() throws InterruptedException %7B%0A        MVar%3CItem%3CT%3E%3E firstItem = start.take();%0A        Item%3CT%3E item = firstItem.take();%0A        start.put(item.next());%0A        return item.get();%0A    %7D%0A%0A    /**%0A     * Writes a new value to the end of the channel.%0A     * %0A     * @param o The object to be put into the current channel.%0A     * @throws InterruptedException If any thread interrupted the current one%0A     * during synchronization.%0A     */%0A    public void write(T o) throws InterruptedException %7B%0A        MVar%3CItem%3CT%3E%3E newItem = MVar.empty();%0A        MVar%3CItem%3CT%3E%3E lastItem = end.take();%0A        lastItem.put(new Item%3C%3E(o, newItem));%0A        end.put(newItem);%0A    %7D%0A%0A%0A    /**%0A     * An item, that is used for storing a value in this Channel.%0A     * %0A     * @param %3CT%3E The datatype of the items value.%0A     */%0A    private static final class Item%3CT%3E implements Supplier%3CT%3E %7B%0A%0A        private final T value;%0A        private final MVar%3CItem%3CT%3E%3E next;%0A%0A        /**%0A         * Creates a new Item, that will wait in a Channel for consumption.%0A         * %0A         * @param value The value this Item holds, MUST be set.%0A         * @param next The following Item, MUST be set.%0A         */%0A        public Item(T value, MVar%3CItem%3CT%3E%3E next) %7B%0A            this.value = Objects.requireNonNull(value);%0A            this.next = Objects.requireNonNull(next);%0A        %7D%0A%0A        /**%0A         * Return the following Item.%0A         * %0A         * @return Next Item.%0A         */%0A        public MVar%3CItem%3CT%3E%3E next() %7B%0A            return next;%0A        %7D%0A%0A        @Override%0A        public T get() %7B%0A            return value;%0A        %7D%0A%0A    %7D%0A    %0A%7D%0A

Implement Channel based off MVar