// Wim H. Hesselink, 23 August 2008

import java.util.* ;

public class Peterson {
    // shared variables
    boolean[] active = { false, false } ;
    volatile int last ;
    volatile boolean crit ;
    Member[] m = new Member[2] ;
    final int TIMES = 1000 ;

    Peterson() {
	for (int p = 0 ; p < 2 ; p++) {
	    m[p] = new Member(p) ;
	    m[p].start() ;
	}
    }

    class Member extends Thread {
	final int self ;
	final int SPEED ;
	Random r = new Random() ;

	Member(int self) {
	    this.self = self ;
	    SPEED = 40 - 4 * self ;
	}

	public void run() {
	    int n = 0 ;
	    try {
		while (n < TIMES) {
		    sleep(r.nextInt(SPEED)) ;
		    active[self] = true ;
		    last = self ;
		    while (last == self && active[1-self]) yield() ;
		    if (crit) throw new RuntimeException("CS violation") ;
		    crit = true ;
		    System.out.print(self) ; yield() ;
		    crit = false ;
		    active[self] = false ; n++ ;
		} 
	    } catch (InterruptedException e) {
		System.out.println("\n " + self + ":" + n) ;
	    }
	    // The exception must be caught outside of the loop.
	    m[1-self].interrupt() ;
	}
    }

    public static void main(String[] args) {
	new Peterson() ;
    }
}

