class QuicksorterWithoutJoin {
	QuicksorterWithoutJoin(Comparable [] arr) {
		this.arr = arr;
		System.err.print(Thread.currentThread().getName() + ": before: ");
		for (int i = 0; i < arr.length; i++)
			System.err.print(arr[i] + " ");
		System.err.println();

		new QuicksortThread(0, arr.length-1).start();

		while (threads > 0)
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}

		System.err.print(Thread.currentThread().getName() + ": after: ");
		for (int i = 0; i < arr.length; i++)
			System.err.print(arr[i] + " ");
		System.err.println();
	}

	class QuicksortThread extends Thread {
		QuicksortThread(int lb, int ub) {
			threads++;
			this.lb = lb;
			this.ub = ub;
		}

		public void run() {
			System.err.println(Thread.currentThread().getName() + ": started with lb: " + lb + " ub: " + ub);
			int pos;
			if (lb < ub) {
				pos = partition(arr, lb, ub);
				System.err.println(Thread.currentThread().getName() + ": partitioned at " + pos);
				new QuicksortThread(lb, pos-1).start();
				new QuicksortThread(pos+1, ub).start();
			}
			threads--;
		}

		int partition(Comparable arr[], int lb, int ub) {
			int lo = lb, hi = ub, xpos = lb;
			Comparable x = arr[lb];

			while (lo <= hi) {
				while (hi >= lo && x.compareTo(arr[hi]) <= 0)
					hi--;
				if (hi >= lo) {
					arr[lo] = arr[hi];
					xpos = hi;
					lo++;
				}
				while (lo <= hi && x.compareTo(arr[lo]) >= 0)
					lo++;
				if (lo <= hi) {
					arr[hi] = arr[lo];
					xpos = lo;
					hi--;
				}
			}

			if (xpos != lb)
				arr[xpos] = x;

			return xpos;
		}

		int lb, ub;
	}

	Comparable [] arr;
	int threads = 0;

	public static void main(String [] args) {
		Integer [] arr = {12, 17, 2, 34, 5, 1, 3, 15, 29};
		new QuicksorterWithoutJoin(arr);
	}
}


