package lock1;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Klasse die ein Object-Array verwaltet und Methoden zum Tausch von
 * Arrayelementen bereithaelt.
 * 
 * @author Ralf Kunze (rkunze@uos.de), Institut fuer Informatik, Universitaet
 *         Osnabrueck
 * @date 05.05.2007
 */
public class MyArray {
	private Object[] array;

	// Lock-Objekt fuer den synchronisierten Zugriff
	private final Lock LOCK = new ReentrantLock();

	public MyArray(Object[] o) {
		array = new Object[o.length];
		System.arraycopy(o, 0, array, 0, o.length);
	}

	/**
	 * Tauscht innerhalb des Arrays zwei Elemente.
	 * 
	 * @param i1 Index des ersten Elementes
	 * @param i2 Index des zweiten Elementes
	 */
	public void swap1(int i1, int i2) {
		LOCK.lock();

		// Achtung: im folgenden Code kann es zu einer Exception kommen
		// unlock() wird dann nicht mehr aufgerufen.
		Object tmp = array[i1];
		array[i1] = array[i2];
		array[i2] = tmp;

		LOCK.unlock();
	}

	/**
	 * Tauscht innerhalb des Arrays zwei Elemente.
	 * 
	 * @param i1 Index des ersten Elementes
	 * @param i2 Index des zweiten Elementes
	 */
	public void swap2(int i1, int i2) {
		LOCK.lock();

		try {
			Object tmp = array[i1];
			array[i1] = array[i2];
			array[i2] = tmp;
		} finally {
			// Auf jeden Fall finally aufrufen!
			LOCK.unlock();
		}
	}
}
