6.5 million software developers and still going strong

Java Developer Magazine

Subscribe to Java Developer Magazine: eMailAlertsEmail Alerts newslettersWeekly Newsletters
Get Java Developer Magazine: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Java Developer Authors: Stackify Blog, Douglas Lyon, Glenda Sims, APM Blog, Pat Romanski

Related Topics: Java EE Journal, Java Developer Magazine, JavaScript

Blog Feed Post

Closures in Java with Lambdas

My goal was to write a program that starts a thread

In the traditional object oriented programming you’d create a class that implements Runnable with a constructor receiving an object to send notification to, for example:

class MarketNews implements Runnable throws InterruptedException{
    Object parent;
    
    MarketNews(Object whoToNotify){
        parent=whoToNotify;
    }

    public void run(){
       // Do something
       synchronized(parent){
           parent.notify();
       }
    }
}

Turning Runnable into a lambda expression and creating a thread is simple:

  Runnable mNews = () -> {
	// Do something
        // But who to notify????
  }; 
   
  Thread marketNews = new Thread(mNews, "Market News");
  marketNews.start();

But how to let the mNews know who to notify when this “Do something is done?” How to pass the reference to that parent thread? It’s not overly difficult if you understand the concept of closures and know that a method can return lambda expression.

In functional languages like JavaScript a closure is a nested function that knows the context where it was declared (I know, it’s fuzzy, just bear with me). In Java there is not nested function but you can return a lambda expression from a method:

private Runnable getMktNewsRunnable(){
   return () -> {//Do something};
}

Runnable mktNewsRunnable = getMktNewsRunnable();

After running the above code the variable mktNewsRunnable will store the text of the lambda expression that can be used for creating a thread:

new Thread(mktNewsRunnable, “Market News”).start();

But this version of lambda expression still doesn’t know who to notify. Let’s fix it:

private Runnable getMktNewsRunnable(Object whoToNotify){
   return () -> {
      // Do something
      // whoToNotify.notify();
   };
}

Runnable mktNewsRunnable = getMktNewsRunnable(this);

I’m using the fact that when the closure was created by the above return statement, it knew about the existence of the variable whoToNotify in the neighborhood! The rest is easy – just put the call to notify() into the synchronized block to make the Java compiler happy. Here’s the complete working example.

public class TestLambdaWaitNotify {

  private static Runnable getMktNewsRunnable(Object whoToNotify){
      
	return  () -> {
		 try{
	      for (int i=0; i<10;i++){
	       Thread.sleep (1000);  // sleep for 1 second
	       System.out.println( "The market is improving " + i);
	      } 
	      
	      synchronized(whoToNotify){
	          whoToNotify.notify(); // send notification to the calling thread	   
	       }
	    }catch(InterruptedException e ){
	       System.out.println(Thread.currentThread().getName() 
	                                        + e.toString());
	    }  
	};    
  }
	
	
  public static void main(String args[]){
    	
	 TestLambdaWaitNotify thisInstance = new TestLambdaWaitNotify();
	 
	 Runnable mktNewsRunnable = getMktNewsRunnable(thisInstance);
	 Thread marketNews = new Thread(mktNewsRunnable,"");
	 marketNews.start();
   
     
     synchronized (thisInstance) {
    	   try{
    		   thisInstance.wait(20000);  // wait for up to 20 sec
    	   } catch (InterruptedException e){ 
    		   e.printStackTrace();
    	   }
    	 }
     
        System.out.println( "The main method of TestLambdaWaitNotify is finished");
  }
}

The main thread will print the message “The main method of TestLambdaWaitNotify is finished” only after receiving the notification from Runnable or when 20 sec expires. Easy?

Read the original blog entry...

More Stories By Yakov Fain

Yakov Fain is a Java Champion and a co-founder of the IT consultancy Farata Systems and the product company SuranceBay. He wrote a thousand blogs (http://yakovfain.com) and several books about software development. Yakov authored and co-authored such books as "Angular 2 Development with TypeScript", "Java 24-Hour Trainer", and "Enterprise Web Development". His Twitter tag is @yfain