NAVIGATION
Home
Gallery
Java
Linux
Web
Scripts And Utilities
Mobile And Sms
Misc
Contact
pixelWIKI
Nabaz Tag




<<

Blocking Processes With Threads

I was playing at creating blocking processes with threads, so that any task can be run with a timeout. Callbacks are easier when running background processes, but not always appropriate.

Anyway, here is the test code I put together. It's really pointless. There is a blocking process which will accept a number from 0 to 10, and try and randomly generate that same number, blocking until it manages to do so. The calling class will let the blocking class run for 10 seconds before timing out.


1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
package threads.blocking;


/**
 * I demonstrate creating blocking threads - useful for performing tasks with a timeout
 */
public class BlockingThreadTest {

	
	public static void main( String[] args ) {
		new BlockingThreadTest();
	}
	
	
	public BlockingThreadTest() {
		// create the blocking thread
		BlockingNumberGenerator b = new BlockingNumberGenerator( this, 5 );

		// synchronize on this - wait() must own the lock on the object to wait - wait() releases this lock
		synchronized ( this ) {
			// start the blocking thread
			new Thread( b ).start();
			try {
				// set the timeout
				this.wait(10 * 1000);
			} catch ( InterruptedException e ) {}
			
			if ( ! b.success() ) {
				// tell the blocking thread to stop
				b.stop();
				System.out.println( "TIMED OUT WHILE TRYING TO GENERATE THE NUMBER" );	
			} else {
				System.out.println( "SUCCESSFULLY GENERATED " + b.getNumber() );
			}
		}
	}
	
}



/**
 * I am a REALLY pointless class.  I take a reference to a calling class and take a number 
 * from 0 to 10, and try to randomly generate that number every second, indefinitely.
 */
class BlockingNumberGenerator implements Runnable {

	private final Object caller;
	private final int number;
	private boolean completed;
	private boolean run;

	
	public BlockingNumberGenerator( Object _caller, int _number ) {
		if ( _number > 10 || _number < 0 ) {
			throw new IllegalArgumentException( "Number must be between 0 and 10" );
		}
		caller = _caller;
		number = _number;
	}
	
	
	public void run() {
		// stop this thread to allow the calling process to complete its setup - may be redundant
		Thread.yield();
		
		run = true;
		// generate random numbers from 0 to 10 until the target number comes up
		System.out.println( "GENERATING RANDOM NUMBERS UNTIL I GET A " + number );
		int r = -1;
		while ( run && ( r = (int) ( Math.random() * 10 ) ) != number ) {
			try {
				Thread.sleep( 1000 );
			} catch ( InterruptedException e ) {
				// interrupt() may be called by the calling thread, to indicate that a timeout has occured
			}
		}
		
		if ( r == number ) {
			System.out.println( "GOT A " + number + "!!" );
			// set the completed flag
			completed = true;
		}

		// tell the calling thread that we're done - notify() must own the lock on the notifed object
		if ( ! Thread.interrupted() ) {
			// we only need to notify the caller if they didn't interrupt us - in this case that is impossible
			synchronized ( caller ) {
				caller.notify();			
			}
		}
	}
	
	
	/**
	 * I stop the generation of random numbers
	 */
	public void stop() {
		System.out.println( "STOPPED" );
		run = false;
	}
	
	
	/**
	 * @return if I was able to randomly generate the desired number
	 */
	public boolean success() {
		return completed;
	}
	
	
	/**
	 * @return the number I was able to randomly generate, or -1
	 */
	public int getNumber() {
		return success() ? number : -1;
	}
	
}