Friday, 24 July 2015

Blocking queue using 'synchronized' block

public class MyBlockingQueue_Sync {
private Queue items = new LinkedList<>();
private Object lock = new Object();
public void put(String item) {
synchronized(lock) {
System.out.println("Writing");
this.items.add(item);
this.lock.notify();
System.out.println("Written");
}
}
public String get() {
synchronized(lock) {
System.out.println("Reading");
if(this.items.size() == 0) {
this.waitforput();
}
String item = this.items.poll();
System.out.println("Read");
return item;
}
}
void waitforput() {
try {
this.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

My Blocking Queue using Lock interface

import java.util.*;
import java.util.concurrent.locks.*;

public class MyBlockingQueue {
private Queue items = new LinkedList<>();
private Lock lock = new ReentrantLock();
public void put(String item) {
try {
this.lock.lock();
System.out.println("Writing");
this.items.add(item);
}
finally {
this.lock.unlock();
System.out.println("Written");
}
}
public String get() {
try {
System.out.println("Reading");
this.tryLock();
return this.items.poll();
}
finally {
this.lock.unlock();
System.out.println("Read");
}
}
void tryLock() {
while(true) {
this.lock.lock();
if(this.items.size() == 0) {
this.lock.unlock();
sleep();
} else {
return;
}
}
}

private void sleep() {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}

}

Thursday, 23 April 2015

Lambda

@FunctionalInterface
interface SimpleCalculation{
double calculate(double arg);
}

class MyMath{
public double sin(double x){
return Math.sin(x);
}
}

public class Main {

public static void main(String[] args) {
SimpleCalculation fn = (double x) -> Math.sin(x);
MyMath mm = new MyMath();
System.out.println(something(fn, 10));
System.out.println(something((X) -> Math.sin(X), 10));
System.out.println(something(x -> Math.sin(x), 10)); // if only one parameter, no need for ()
System.out.println(something(Math::sin, 10)); //Method reference, if static ClassName::MethodName
System.out.println(something(mm::sin, 10)); //if instance method, instance::MethodName
}
static double something(SimpleCalculation cal, double value){
return cal.calculate(value);
}

}

Wednesday, 21 January 2015

Custom DispatchQueue with a Worker thread

public class DispatchQueue
    {
        Queue<Action> queue = new Queue<Action> ();
        static object key = new object ();
        SingleThreadDispatcher dispatcher;

        public DispatchQueue(SingleThreadDispatcher dispatcher) {
            this.dispatcher = dispatcher;
        }

        public void QueueWork(Action work){
            lock (key) {
                queue.Enqueue (work);
            }

            if (this.dispatcher.Executed) {
                this.dispatcher.Dispatch (this.Dequeue (), SynchronizationContext.Current, this.Callback);
            }
        }

        private Action Dequeue(){
            lock (key) {
                if (queue.Count <= 0) {
                    return null;
                }

                return queue.Dequeue ();
            }
        }

        private void Callback(object state) {
            var work = this.Dequeue ();

            if (work == null) return;

            this.dispatcher.Dispatch (work, SynchronizationContext.Current, this.Callback);
        }
    }


public class SingleThreadDispatcher
    {
        Task task = null;

        public void Dispatch(Action work, SynchronizationContext context, Action<object> callback) {
            if (work == null || context == null || callback == null || !this.Executed) {
                return;
            }

            Action safeWork = () => this.Execute (work);
            this.task = new Task (safeWork);
            this.task.ContinueWith ((result) => {
                context.Post(new SendOrPostCallback(callback), null);
            });

            this.task.Start ();
        }

        public bool Executed {
            get{
                return (task == null) || (task != null && task.IsCompleted);
            }
        }

        private void Execute(Action work)
        {
            try {
                work();
            }
            catch(Exception e) {
                //
            }
        }
    }