Multi-blocking pattern

As some of you know I’m currently preparing for a set of interviews for a job, and in the process of patching old work for show I came across an idea for a pattern I call the multi-blocking pattern.

What is it and why is it needed
The multi-blocking pattern provides an interface by which you can create classes which with methods that are both non-blocking and blocking. This allows you to - for example - write simple AI routines, for example here is a really simple Clue AI routine.

void aiTakeTurn () {
   evaluatePlans ();
   rollDice().complete();
   evaluateRange();
   moveToken().complete();
   suggest().complete();
   viewSuggestedCards();
   if ( isSureOfEvidence () ) accuse ();
}

Explanation of example

So what happened there? Well if your game is event driven and [say] running over a network then you end up splitting a particular routine over to the event handlers, or coming up with potentially flawed schemes to provide for linear coding. All that happens is that the model-control interface methods return a handle to the operation that is carried out, where complete will wait until the completion conditions are met.

Sure it’s simple and isn’t exactly going to cure cancerous code bloat, but it’s got to be a useful approach to give to learner software engineers / computer scientists who are developing software that will probably have a need for both approaches. And it’s a pattern with a name!

I have a similair approach, using a ThreadPool (with 1 thread if I need queue-like behaviour).


ThreadPool pool = new ThreadPool(1);
Task task = pool.addTask(new Runnable(){ ... });

task.waitFor();
task.waitFor(ms);

// or
pool.barrier();
pool.barrier(Runnable);

Implementing your interface with this backing would be easy, so although the approach is kinda different, under the hood it’s probably all the same :slight_smile:

To be honest, I think these async ‘patterns’ are pretty much implemented by anybody who has dealt with multi-threading in a non-trivial situation.

Sorry, but I don’t get to that “pattern” your explaining, though I’m used to usual forms of abstract models for Java. Hence I’ve got two questions:
-What’s the very goal of that concept?
-Is it that you are facing a multi-threaded env. that you want to synch and gather the completed threads at once or do you want to describe something more abstract?


ExecutorService processor = Executors.newSingleThreadExecutor();
Future<?> future = processor.submit(new Callable<String>() {....}); 

future.get();
future.get(timeout, unit); 

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/package-summary.html

and tbh I think the termonoligy of the java api is most elegant, although get looks a bit wrong here. But if I care about if something is done or not I usually want to know how it completed.

It’s just for implementations where you want it to be able to work using both events, and linear coding. It’s like getting user input, sometimes you just want to write n = getInput(), but you also want the system to work with just events for them. And yes it’s in a multi-threaded environment where you may want to code linearly.

Riven’s approach is about the same, which is why it is a pattern. We are achieving the same goal, and if there is a common approach to achieving a solution to the same problem then there is a design pattern others can use.

I’ve called the class JobTicket, let me know what you think? Sure it’s nothing new thought wise, but it’s a reusable class for beginners.

/**
 * <p>
 * 		A job ticket is a synchronisation object that can be used
 * 		to issue jobs that may or not complete immediately. For example
 * 		you may make a call to <b>clean a window</b>, the job may be performed
 * 		immediately or may incur a delay.
 * </p>
 * <p>
 * 		Depending on your implementation you may opt to create a
 * 		solution where you respond to a job completion event, you may wish
 * 		to wait for completion, or you may wish to do a bit of both. By using
 * 		a JobTicket you can create an class method that is accessible by
 * 		both approaches.
 * </p> 
 * @author Keldon
 */
public class JobTicket {
	private State state;
	public enum State {
		INCOMPLETE, FINISHED, FAILED
	}
	
	/**
	 * Creates a new JobTicket instance, and initialises the variables.
	 * At this state the job is incomplete.
	 */
	public JobTicket (){
		this.state = State.INCOMPLETE;
	}
	
	/**
	 * returns the state of the JobTicket
	 */
	public State getState (){
		return this.state;
	}
	
	/**
	 * This method waits for the job to be completed. If it is already completed
	 * then the method will return. 
	 */
	public JobTicket synchronise (){
		synchronized (this){
			// if the job is not completed then wait
			while (state == State.INCOMPLETE){
				try {
					wait();
				} catch (InterruptedException e) { }
			}
		}
		
		return this;
	}
	
	/**
	 * Completes the job, any waiting threads in the synchronise method will
	 * be notified, and any future calls to synchronise will not wait.
	 */
	public JobTicket taskFinished (){
		synchronized (this) {
			this.state = State.FINISHED;
			notifyAll();
		}
		
		return this;
	}
	
	/**
	 * Completes the job, any waiting threads in the synchronise method will
	 * be notified, and any future calls to synchronise will not wait.
	 */
	public JobTicket taskFailed (){
		synchronized (this) {
			this.state = State.FAILED;
			notifyAll();
		}
		
		return this;
	}
	
	/**
	 * Demonstrates a JobTicket scenario with two cases. One case has the
	 * job sleeping for a second and the synchronise call has to wait,
	 * the second case has the job performed before synchronise is called.
	 */
	public static void main (String argv[] ) throws InterruptedException {		
		final JobTicket printTicket1 = new JobTicket();
		final JobTicket printTicket2 = new JobTicket();
		
		
		Runnable job1 = new Runnable(){
			public void run() {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) { }
				
				System.out.println ("Printing 1");
				printTicket1.taskFinished();
			}
		};
		
		Runnable job2 = new Runnable (){
			public void run () {
				System.out.println ("Printing 2");
				printTicket2.taskFinished();
			}
		};
		
		new Thread(job1).start();
		printTicket1.synchronise();
		System.out.println ("Ticket 1 done");
		
		new Thread(job2).start();
		Thread.sleep(1000);
		printTicket2.synchronise();
		System.out.println ("Ticket 2 done");
	}
}

class JobTicket demo above is good enough but will make a better synch if the wait() is replaced by the correct loop:

synchronized(monitor) { 
   while(stateNotOK) {
       monitor.wait(10); // this timed wait is better to make sense of "Tickets", where the monitor can be replaced by the current instance a.k.a "this"
       System.out.println("Ticket waiting...");
   }
}
System.out.println("Ticket accepted.");
//(...)
      

BTW that’s what I’d call a “multi-block pattern”. ;D

Seems like a very verbose way of implementing Thread.join() ?

join() may behave the same way, as well.

It does do a similar thing, but you get the added return status bonus. Although having said that maybe a state object implementing runnable that starts a thread would do that better. I’ll look into that, because something like ReturnState.join() might actually make more sense.

And yes that is much more like ticket waiting behaviour, now you just need to add code simulating queue jumping and unnecessary delays :wink: Having said that the classes implementation doesn’t need a timed wait, but then again that while should be replaced with an if statement - it only had the while because I previously had it where you could change the state … to INCOMPLETE. Then I replaced the changeState method with the ones there.

Java has some stuff like Future and Task which actually allow return values for threaded objects which do not have the value right now but will have them at some point in the future. My experience is, when something is useful, it already exists. You just dont know how its called or where to search.

-JAW

on my knowledge I never have seen any programmatic language before Java that permits alike synch concepts. Now I can get a rendering-screen fully synchronized with such wait-for-thread patterns that are not available with PHP or Basic. This and other capabilities of Java have got many future consequences to new OS’es and virtual logic systems, for example faster AI and smarter robotics as well as robust softwares. 8)

Since then I don’t imagine that the Java programmers will take much more changes to the language architecture. Moreover programmers that are announcing new “patterns or design concepts or even logical algorithms” may not be as far as they’d think so, technically meant. I’d say to practice more on your own to get more experience on Java programming and thereby announce that you discovered a new software application, not an unknown pattern or concept… That sounds fuzzy… ( c’est dérisoire en français ) ::slight_smile:

Random thought: it takes little to create code that fulfils a particular requirement; but it takes great visionary to see the greater general use of an approach for others to follow… the way I write I should write books lol

I really can’t see what the fuzz is all about. When dealing with concurrency these are the first things you tend to do. It’s not so much a pattern, it’s simply the way to deal with threads. And then, it’s not really that fancy, the first thing you learn in class is to let thread A wait for thread B until a condition is met, with some wait/notify constructs. As I pointed out earlier, it’s much like a waitFor or a barrier: wait until thread A,B,C and D are done, then do something else. What is the pattern? It’s simply using concurrency, not even in some clever way.

You sound upset, would you like a cup of tea 8)

Of course we learn to wait, notify, etc. although now you mention it what is “fancy” about any pattern exactly? Using typical thread behaviour is fine, but here it looked a little tidier, in the implementation. I was mainly using the class where my implementation could wait or use events, if you look at the code you can see that it doesn’t necessarily need to invoke a thread. You can define an interface that returns the ticket, and the interface could be async or serial, you don’t need to care, either respond to the message or wait.

You can write it in a more verbose way, but its a lot nicer when writing an interface (in some cases) where you can define your methods to perform methods whenever they feel like it, or straight away, where it will return a ticket that is already completed.

Patterns are there to guide the programmer to program in a generally accepted way. A proven way to design things. What your code does is simply using basic functionality, not following a clearly defined way. As mentioned earlier, it behaves like Thread.join(), which also isn't a pattern in itself. That's why I'm a little agitated (maybe) because some people - especially broumbroum - are threating it as the next best thing, while there isn't much to it.

Nah, he says its like thread.join, and that it “sounds fuzzy”. Probably pattern was the completely wrong word to use, but it really made the interface spec a lot nicer in my cluedo code where I could specify a function that could be implemented in either async or serial.

Having said that you could just as easily have the interface return a Thread to join, or run and wait for synchronization. Although with a ticket you only wait in a queue when the job isn’t done. Nothing special really I guess, it’s just covered up the decision underneath a little but as an example of what I was doing …

You have moves like:

  • moveToken(position)
  • makeSuggestion (suggestion)
  • makeAccusation (suggestion)

And you have events like:

  • tokenMoved()
  • suggestionDisproofRequested()

With the ticket you can have the implementing players either sending messages and waiting for events, or you could write your AI with simple methods like makeSuggestion ().complete() … and then retrieve the card. Without that you have to explicitly involve threads and real synchronization. But if anything its just a good way of handling this type of behaviour in an interface, you can dress it up in many other ways too (naturally).

Maybe it was just my response to looking at second year uni work and thinking yuk, there is a problem. I liked the idea of an API that could work with thread-ignorant code but also thread-aware code too.