public class DeadLockWithResourceMgr {
	public static void main(String argv[]) {
		int resources[] = {1,1};
		ResourceMgr rMgr = new ResourceMgr(resources);
		for (int i=0; i<Integer.parseInt(argv[0]); i++)
			new Thread(new BlockingThreadResourceMgr(rMgr) ).start();
	} //main()
} //class DeadLockWithResourceMgr

class BlockingThreadResourceMgr implements Runnable {
	ResourceMgr rMgr;
	
	public BlockingThreadResourceMgr(ResourceMgr rMgr) {
		this.rMgr = rMgr;
	} //constructor
	
	public void run() {
		System.out.println(Thread.currentThread().getName()+" is sleeping");
		try {
			Thread.sleep( (int) (Math.random() * 0) );
		} //try
		catch (InterruptedException ie) {
			System.out.println("An InterruptedException caught\n"+ie.getMessage());
			ie.printStackTrace();
			System.exit(1);
		} //catch()
		int requestedResource1=(int) (Math.random()*1.1);
		int requestedResource2=Math.abs(requestedResource1-1);
		int resourceV[] = {requestedResource1, requestedResource2};
		
		System.out.println(Thread.currentThread().getName()+" requests resources ["+resourceV[0]+","+resourceV[1]+"]");
		rMgr.request(resourceV);		
		System.out.println(Thread.currentThread().getName()+" locks resources ["+resourceV[0]+","+resourceV[1]+"]");
		try {
			Thread.sleep( (int) (Math.random() * 0) );
		} //try
		catch (InterruptedException ie) {
			System.out.println("An InterruptedException caught\n"+ie.getMessage());
			ie.printStackTrace();
			System.exit(1);
		} //catch()
		
		//deadlock prone section begins
		int otherResourceV[]={requestedResource2, requestedResource1};
		System.out.println(Thread.currentThread().getName()+" requests resources ["+otherResourceV[0]+","+otherResourceV[1]+"]");
		rMgr.request(otherResourceV);
		System.out.println(Thread.currentThread().getName()+" locks resources ["+otherResourceV[0]+","+otherResourceV[1]+"]");
		try {
			Thread.sleep( (int) (Math.random() * 0) );
		} //try
		catch (InterruptedException ie) {
			System.out.println("An InterruptedException caught\n"+ie.getMessage());
			ie.printStackTrace();
			System.exit(1);
		} //catch()
		rMgr.release(otherResourceV);
		System.out.println(Thread.currentThread().getName()+" released resources ["+otherResourceV[0]+","+otherResourceV[1]+"]");
		//deadlock prone section ends
		rMgr.release(resourceV);
		System.out.println(Thread.currentThread().getName()+" released resources ["+resourceV[0]+","+resourceV[1]+"]");
	} //run()
} //class BlockingThreadResourceMgr			
			