package lock2;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Diese Klasse stellt einer verkettete Liste dar.
 * Da beim Einfügen theoretisch mehrere Threads beteiligt sein könnten, so dass es
 * zu Problemen kommen koennte, wird der kritische Bereich mit einem
 * Lock versehen. In diesem Beispiel werden die einzelnen ListenEintraege
 * gelockt.
 * 
 * @author  Ralf Kunze (rkunze@uos.de), Institut fuer Informatik, Universitaet Osnabrueck
 * @date 05.05.2007
 */
public class MyLinkList {
	Object value;
	MyLinkList rest;
	Lock lock;
	
	public MyLinkList(Object value) {
		this.value = value;
		rest = null;
		// Jede Node bekommt ihren eigenen Lock
		lock = new ReentrantLock();
	}
	
	/**
	 * Am Ende der Liste ein Element anhaengen.
	 * @param o Anzuhaengendes Element.
	 */
	public void append(Object o) {
		// aktuellen Knoten merken
		MyLinkList node = this;
		
		// aktuellen Knoten sperren
		node.lock.lock();
		
		// Ans Ende der Liste wandern
		while(node.rest==null) {
			MyLinkList next = node.rest;

			// Bereits versuchen den naechsten Eintrag zu sperren
			next.lock.lock();
			// Den vorherigen Knoten freigeben
			node.lock.unlock();

			// Weiterwandern
			node = next;
		}
		
		try {
			// Am gesperrten Knoten einen weitern anhängen
			node.rest = new MyLinkList( o);
		} finally {
			// Sperrung wieder aufgeben
			node.lock.unlock();
		}
	}
}
