DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. Project Coin: the try-with-resources lock support debate

Project Coin: the try-with-resources lock support debate

Martijn & Ben Verburg & Evans user avatar by
Martijn & Ben Verburg & Evans
·
Mar. 29, 11 · Interview
Like (0)
Save
Tweet
Share
5.88K Views

Join the DZone community and get the full member experience.

Join For Free

If you have recently been following Project Coin’s mailing list , you will have spotted an interesting discussion regarding the inclusion of lock management inside the scope of a try-with-resources (TWR) code block.

The Initial Idea

The idea was initiated by Gernot Neppert who proposed a class java.util.concurrent.AutoLockable which would implement AutoCloseable, and therefore be eligible for usage with TWR:

package java.util.concurrent.locks;

public abstract class AutoLockable implements AutoCloseable
{
public static AutoLockable locked(final Lock lock)
{
lock.lock();
return new AutoLockable()
{
@Override
public void close() {
lock.unlock();
}
};
}

public abstract void close();
}

Its usage would be something like this:

try(AutoLockable locked = AutoLockable.locked(lock))
{
// Do something in locked scope
}

This proposed idea certainly has merit, however the sharp eyed amongst you will notice a performance issue in creating a new object each time you perform a lock. Additionally, you would also have to have an extra method to acquire the lock (the locked(...) method in the above example). So what else could be tried?

An Alternative Idea

Dr Heinz M. Kabutz posted a link to a newsletter where he describes an interesting way of using JDK 7′s TWR to automatically unlock Java 5 locks. Long story short, the main idea is to build a wrapper class around a Lock, which implements AutoCloseable and manually unlocks in the close() method. The wrapper along with usage of static imports would bring verbose code like:

lock.lock();
try
{
printLockStatus();
}
finally
{
lock.unlock();
}

… to a more readable form:

try (lock(lock))
{
printLockStatus();
}

However, as the author himself mentioned, the problem of creating extra objects every time you perform a lock still remains. Moreover, as David Holmes signaled in the mailing list, the spec has been updated to prohibit usage of resources as general expressions in the TWR argument and only allow passing them with an accompanying explicit variable declaration.

Why TWR (as it stands) can’t support this

Among the reasons for this update were difficulties encountered by the parser which was not always able to distinguish between the start of an expression and the start of a type:

try(i < j // Ternary operator on variables i and j
? new Resource1() :
new Resource2()) {...}

… compared to code like

try(Box < Resource // Simple generic wrapper around a resource
> resourceBox = Box<>(new Resource1())) {...}

Another reason for change was the use case of managing an existing variable which changes its value inside the try block. The example presented on the update site is the following:

public class TwrExamples implements AutoCloseable
{
public static void main(String... args)
{
TwrExamples twrEg1 = new TwrExamples();
System.out.println(twrEg1.hashCode());

try(twrEg1)
{
twrEg1 = new TwrExamples(); // Mutating the variable!
System.out.println(twrEg1.hashCode());
}
}

@Override
public void close()
{
System.out.println(hashCode());
}
}

.. where close() will be called on the first twrEg1 instance, not on the one pointed to at the time the try block finishes. Thus, output results after running a TWR having a TwrExamples resource as argument, may look like this:

1607576787
1051296202
1607576787

The documentation of the Project Coin features posted on March 1st 2011 by Joe Darcy further strengthens the rule of requiring variables to declare a resource in detriment of using general expressions:

“A resource specification declares one or more local variables; the type of each variable must be a subtype of AutoCloseable or a compile-time error occurs.”

However, assigning a new variable to an already existing one referring to the lock just because TWR prohibits identifiers seems troublesome. There is a section in the JSR 334 spec changelog stating that:

“One potential future extension is to allow a resource to be specified as an expression that is a final or effectively final variable. Such a restricted expression form would remove the need to declare a resource variable for the sole purpose of aliasing an existing variable while avoiding pathologies stemming from the resource variable being modified within the body of the |try|-with-resources statement.”

Joe Darcy states in the mailing list that even though this change is too late to be applied to JDK 7, it would be a nice addition to JDK 8.

Some Extra Analysis

Another heads-up in this direction is related to constructs such as try (Resource r = getResource()), where methods such as getResource() are not expected to fail. Some workarounds are proposed by Reinier Zwitserloot in coin-dev, for example not considering the expression Resource r = getResource() as part of the try, and do something like this try (Resource r = ...) { try { ..... }} . Another solution would be setting r to null if the exception that triggers the catch block is resulted from getResource() method. The example from the mailing list is :

try (Resource r = getResource())
{
/*.... */
}
catch (Exception e)
{
icon = Icons.DEFAULT_ICON;
logger.log("App icon resource " + r.getURL() + " is not available", e);
}

In this case we would prefer obtaining a NullPointerException in the log, rather than a core dump.

Your Thoughts?

We’re curious to find out any opinions the readers of this blog might have regarding this ongoing topic discussion on coin-dev. Do you think automatic TWR lock support might be useful to you?

 

From http://www.java7developer.com/blog/?p=256

Threading COinS

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • What Are the Benefits of Java Module With Example
  • Stop Using Spring Profiles Per Environment
  • Real-Time Analytics for IoT
  • How We Solved an OOM Issue in TiDB with GOMEMLIMIT

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: