Archive | Design RSS feed for this section

Design Robust Restful API

This article is to summarize some key design decisions related to exposing some in-house services through REST API to the public. It involves url path design based on “resource oriented model”, version control, authentication and authorization and asynchronous call handling.

URL Path Design

Check out this video first:

  • Use resource oriented model - Every resource type should be a Noun that is normally represented as a collection. On the other hand, HTTP verbs (GET, PUT, POST, DELETE) will be used to manipulate the resources.
    • GET: read (cacheable)
    • PUT: modify (caller provides id)
    • POST: create the resource and use to call method as RPC.
    • DELETE: remove
  • Each resource should have 2 apis only: one for the collection in plural form, one for a particular entity.
  • The collection one can have ?search=… for locate the set of entities you want.
  • No verb should be in the url path.
  • Complex variation should use ?xxxx to take care of. Don’t complicate your url.
  • Pagination prefers to use ?offset=50&limit=200
  • Field extraction: field extraction uses ?fields=xxx,yyy
  • Formatting: take advantage of file extension like dogs.json
  • For input parameters, put everything into the URL and not using the HTTP headers, which is used for OAuth headers.
  • Error handling: Use HTTP error code to indicate error in the server side. (ie. 200 = succeed, 400=application error and 500 = wrong request, is used if the API). A human readable error message, together with the hint to fix that, should be sent back in the HTTP body response.
  • Operations can be sync vs async.
  • In GET operation, by default the container only return the URL reference of its immediate children. An optional parameter “expand” can be used to request the actual representation of all children and descendant.
  • API should only expose the function semantics but nothing about its implementation details, which allows the implementation to continuously evolve without breaking the client interface. And a good API should focus to do one thing well, rather than multiple things of different purposes. Each API must be self-contained and not relying on any specific call sequence to work correctly.

Example:

  1. List all persons. GET /persons
  2. Find a person with a particular id. GET /persons/123
  3. Get partial fields. GET /persons/123?fields=(name,age)
  4. Find a person’s particular friend. GET/persons/123/friends/456
  5. Find all persons named John. GET /persons/search?q=(name,eq,John)
  6. Find all dogs whose master is John. GET /persons/search?q=(name,eq,John)/dogs
  7. Create a person with a server assigned id. POST /persons?name=Dave&age=10
  8. Create a person with a client assigned id. PUT /persons/123?name=Dave&age=10
  9. Ask the person to perform an action. POST /persons/123/action/travel?location=Euro
  10. Remove a person. DELETE /persons/123
  11. Return a page of result. GET /persons/search?q=(name,eq,John)&offset=1&limit=25

Async call handling

In case when the operation takes a long time to complete, an asynchronous mode should be used. In a polling approach, a transient transaction object is return immediately to the caller. The caller can then use GET request to poll for the result of the operation. We can also use a notification approach. In this case, the caller pass along a callback URI when making the request. The server will invoke the callback URI to POST the result when it is done.

Versioning

  • If you follow the minimal API design approach, the newer version is usually about adding parameters to your original API rather than removing parameters.
  • Backward compatibility via using the same URL. (e.g. http://xyz.com/v1/path/…). On the implementation side, you only have the implementation that takes the latest version API parameters as input. In other words, you are prepared to receive request of the older version as well as the latest version. But you substitute the default value of the parameters of the newer version that is missing in the older version. And then send this request (with all the parameters filled) to the latest implementation.
  • For incompatible change, use a different URL endpoint for the new version (e.g. http://xyz.com/v2/path/…). You also keep the corresponding implementation (v1 and v2) behind those endpoints. Depends on your decision whether to keep supporting the older version, you may want to introduce a deprecation process. Unfortunately there is no standard way to indicate an API will be deprecated in the response. One possible way is to put a flag in the HTTP header of the response to indicate when the API will be deprecated.
  • Most people put versioning info as part of url like (e.g. http://xyz.com/v1/path/…). But it is debatable as others see versioning shouldn’t be part of url instead you can play trick in content type to specify what version of content you want.
Reference
  1. http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html

Authentication and Authorization

Authentication call which must the first call to make and precede any other application API calls. As far as API security, App level key, with OAuth2.0 protocol should be used for authentication and authorization purpose.

Leave a comment Continue Reading →

Unit Testing – Async method

Most Unit testing frameworks assumes a synchronous call model that the calling thread will block until the called method returns. So a typical test method will look like the following …

1

However, this model doesn’t fit if the call is asynchronous; ie: the calling thread is not blocked and the result will come later from a separated callback thread. For example, if you have the following AsyncService, where the “call()” method returns immediately and the result comes back from a callback interface.

1

The test method need to be changed. You need to block the calling thread until the result comes back from the callback thread. The modified test code will look like the following …

1

In this test method, the calling thread is waiting for the callback thread. A latch is used for the synchronization. You cannot use Thread.wait() and Thread.notify() for this purpose because there is a possibility that notify can be called before the wait and then one thread will wait indefinitely. Latch is a once-off switch and if the “release” is called first, then all subsequent “attempt” call will return immediately.

Leave a comment Continue Reading →

Top Programmer Code Practice

Information Hiding

  1. Promote encapsulation and data hiding
  2. Expose clean API and achieve high decoupling and in turn promote reusability. So, modules can be developed in parallel and fix in isolation.
  3. Achieved in Java by access control (public, protected, package-private, private). Top level (non-nested) class can only be package-private and private. Public imposes maintenance cost! Once your API public or protected access, you must support it.
  4. If a class A is only used by one class B, consider to make A private nested class of B.
  5. Instance fields should never be public. Public mutable field is not thread-safe whereas public immutable field limits you from changing data type. Even you expose constant value, make sure it is public static final on a primitive or on a reference to an immutable object. NOTE: Array is mutable. Use immutable List instead.
  6. There is one rule that restricts your ability to reduce accessibility of methods. If a method overrides a superclass method, it is not permitted to have a lower access level in the subclass.

Code Against Interface

Promote Immutability

  1. Make its properties private and final
  2. Take away any API that can change its properties
  3. Make your class "final" to prevent subclassing.
  4. Immutable object can be shared and thread-safe

Favor Composition over Inheritance

  1. It is safe to use inheritance within a package but not cross package
  2. It is also safe to use inheritance when extending classes specifically designed and documented for extension.
  3. Interface inheritance is good. The above rules apply to implementation inheritance b/c it will violate encapsulation as subclass depends on implementation details of its superclass and superclass may change from release to release. Sometimes, superclass may break your security rules that you impose on the subclass. To avoid those problems as a whole, use composition. Along with forwarding class, the design is clean.

Scalability vs Performance

Performance measures whether an application can respond to a request within its defined service-level agreement (SLA). Scalability measures how well an application can maintain its performance under increasing load.

  1. Horizontal scaling – To scale your system horizontally, the key problem you need to solve is how to replicate the state effectively. Serialization is primitive as it will replicate the full state (can be big) even one small field is changed. This approach's inefficiency hinders linear scalability. To overcome the limitations of Java serialization, Terracotta uses bytecode instrumentation (BCI) in the Terracotta client to identify the exact properties within stateful objects that change and then replicate only those properties across the cluster (fine-grained replication). Bytecode instrumentation is a process through which an application's behavior can be modified at runtime. NOTE: Bytecode instrumentation is a process through which an application's behavior can be modified at runtime. Terracotta uses BCI to intercept changes made to objects so that it can identify those changes and send them to the Terracotta server (hmm, it is not purely peer to peer approach).
Leave a comment Continue Reading →

Session Management – Part 1

Session management is one of the key topics that all serious web developers and architects need to master with. This article will go through several key topics with you. They are:

  • Persistence vs non-persistence web connection – web performance!
  • Concerns of using cookie – security and size limitations
  • Server side session management challenges in scalable web application
  • Achieve linear scalability through stateless servers - start moving the session to the client

Today, I will start walking through all these topics at a high level. A series of articles will be written to further develop on each topic if necessary. Lets start!

Persistence vs non-persistence web connection

  1. Before HTTP 1.1, HTTP is a stateless protocol that doesn't maintain persistence connection. Each request made by a Web browser, for an image, an HTML page, or other Web object, is made via a new connection.
  2. HTTP 1.1 introduced persistence connection (ie. Keep-Alive) that Web browser can established a single connection, through which multiple requests could be made.
  3. But before HTTP 1.1, how can state maintain across stateless HTTP request?
    • Normally, we keep the session in the server side and provide the session id to the client that can be used to link subsequent requests to the same session.
    • Normally, client (often time web client) will store the session id in cookie.
    • However, if the cookie is disabled, the session id will normally embedded in the URL (ie URL Rewriting).

Concerns of using cookie

What do we need to pay attention when we store info in cookie?

  1. Size limitation and security concerns.
  2. How long cookie can last? Default = expired when browser exits. In Java, you can do cookie.setMaxAge(int) with long future date if you want to keep the info lasting long in the cookie. If you do setMaxAge(0), it will void the cookie.
  3. Normally, we don't keep all state info in cookie as the information could be sensitive and we are not able to protect it because it sits in the clients' filesystem. Apart from that, there has limitation in size as well. For these two concerns, we normally just store the session id in the cookie and keep the session in the server side. This approach can save us bandwidth as well.

Server side session management challenges

At the first glance, session in server side sounds like a great solution. However, when it comes to scale, it always raises the concerns. Imagine you need to replicate client session state across multiple servers to achieve high availability. Both the replication time and memory resource limit will cause your system not able to scale linearly. To solve or minimize this, we selectively pick what kind of info we store in the session, use sticky session to avoid one session replication across all the machine or even try to store the state to the client if possible like using rich client UI (ex. Flex and Silverlight). A post will be written about this topic later on.

Transient vs Persistent State

  1. Session in the server can be timed out (~30 minute inactive)
  2. Session in the server can be persisted in file across Tomcat restart.
  3. Persistent state should be stored in database.
  4. Object putting in session should be Serializable
  5. Avoid putting too much info in the session b/c we don't want to put too much baggage during session replication. One server crash b/c of memory depletion can further spread across to other servers via session replication. Not Good! Should we reconsider storing session in client? This article talks about it.
  6. Session replication is needed to support failover. Sticky session for simplicity but suffered data lost when the box is down. We can tell one or two servers as its backup to avoid the session lost. To go for sticky session approach, we need to identify the "sticky" part. What kind of thing we can use to link separate requests? Use IP address can potentially overload a box because some Internet service providers use a set of proxy servers to deal with many clients. This subject can be further developed. We will go back to it later!
Leave a comment Continue Reading →

Learning Hive

Starting to learn Hive

As I mentioned in my last article,  I was getting excited about the potential of Hive. Today, I decide to start my journey to learn this. I found a great introductory video that gives you a nice warm-up of using Hive (A basic knowledge of how hadoop and mapreduce work would be helpful for you to digest the material inside).

Below are some highlights from this video

Hive is an SQL interface built on top of Hadoop. It supports Web access and JDBC. I am amazed how close the SQL syntax like the regular SQL for RDBMS. Below are some SQLs used in this tutorial.

//———- Set up your tables in HIVE —————–
SHOW TABLES;

CREATE TABLE shakespeare (freq INT, word STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’ STORED AS TEXTFILE;

DESCRIBE shakespeare;

//———- Load data into Hive table from Hadoop HDFS ——————-
LOAD DATA INPATH “shakespeare_freq” INTO TABLE shakespeare;

//———- Query against the data using hive sql interface ————–
select * from shakespeare limit 10;
select * from sakespeare where freq > 100 sort by freq asc limit 10;
select freq, count(1) as f2 from shakespeare group by freq sort by f2 desc limit 10;

//show me the plan
explain select freq, count(1) as f2 from shakespeare group by freq sort by f2 desc limit 10;

//———- Create a merge table and populate it using dataset joining by 2 different tables
insert overwrite table merged select s.word, s.freq, k.freq from shakespeare s join kjv k on (s.word = k.word);

//———- Query the merge table ———————
select word, shake_f, kjv_f, (shake_f+kjv_f) as ss from merged sort by ss limit 20;

To prepare the data for Hive to load in, the demo uses another mapreduce job to achieve. Remember to delete the log before doing Hive table load.

hadoop jar $HADOOP_HOME/hadoop-*-examples.jar grep input shakespeare_freq ‘\w+’

//remove the mapreduce job log
hadoop fs -rmr shakespeare_freq/_logs

Often time, large scale data processing system always IO bound. So for mapreduce job, your mapper is always waiting for data to load from disk. Hadoop mitigates the problem via during parallel load from lots of hard drives. However, a single hard drive is still max out at 75MB/s read as physical limit and nothing we can do about this. In order to achieve good speed, the key is to eliminate # of hadoop pass

Since Hive is on top of Hadoop’s HDFS, it will have the same restrictions as it. So, you cannot do UPDATE, DELETE and INSERT records as regular RDMS. However, you can do bulk load to add more new files (data) to the table and you can do delete a file from Hive.

Hive needs to store metadata of the tables out from the HDFS. You can use regular rdms to achieve the job. But when you start Hive locally, it will seek for the local metastore. So, in distributed environment, you may need to centralize the metastore in a remote location. There is wiki on the Hive site that documents how to set it up.

See Hive in Action

Cloudera Hadoop Training: Hive Tutorial Screencast from Cloudera on Vimeo.

Other projects similar to Hadoop

  • Parallel databases: Gama, Bubba, Volcano
  • Google: Sawzall
  • Yahoo: Pig
  • IBM Research: JAQL
  • Microsoft: DryadLINQ, SCOPE
  • Greenplum: YAML MapReduce
  • Aster Data: In-database MapReduce
  • Business.com: CloudBase
Leave a comment Continue Reading →

Hive on Amazon EC2 cloud

adserving-ec2-hive-system-arch

 

I ever worked for a display ad network company that collects over 400 million of impression/ click logs per day. With this amount of data, my ex-company bought a supercomputer and cross their fingers that it can handle the grow in both volume and analytic demand of the data. It is obviously not a scalable solution. However, what is the best solution?

Although I haven’t worked for this company anymore, it is still an interesting problem to solve. I have a great friend who proposed a shared nothing solution for this company. The solution is to partition the data across a set of Postgresql databases and put Greenplum on top of them to parallelize the query —there is no disk-level sharing or contention to be concerned with (i.e. it is a ‘shared-nothing’ architecture). I like this approach. The only thing is that Greenplum is not free and it may be difficult for a startup to face this upfront cost. Apart from that, this setting requires all the databases are running on the same network that hindered us to move this in the elastic cloud like Amazon EC2.

Later on, I joined a great company in the same industry that seeks for a solution in the cloud to host its data warehouse. So, I got a  chance to revisit this problem. During the research, I came across an interesting technology – column-based database (eg. infobright and lucid db). The idea of column-based data store is that traditional database stores and fetches data in row from data files into the memory. It is inefficient if your query only requires few columns for computation. So, column-based data stores your data in column with effective compression algorithm due to all values in it has the same data type. This solution is great but it doesn’t do MPP (ie. massive parallel processing) and it is also not ready for cloud yet.

Here comes another solution. That is Hive on top of Hadoop on top of Amazon cloud. It is an interesting idea. Check out this video to learn about this.


If you are not sure what Hadoop is and want to get some warm up in massive computing. I suggest you go through the following 5 excellent Google lectures.


Leave a comment Continue Reading →

Powerful combination: JMX + Annotation + AOP

What is AOP?

AOP is a way to modularize cross-cutting concerns. Ok, what does “modularize” really mean? Modularization is the encapsulation of a unit of functionality. It is exactly what “Class” is doing in OO world. How about “cross-cutting concerns”? Basically it means any functionalities that span multiple modules/ classes. They include Transaction Management, Security, Caching, Performance Monitoring and etc. To understand how AOP works, we first look at the common terms in this area:

  1. Join point – An identifiable point in the execution of a program like method invocation, exception thrown.
  2. Pointcut – Program construct that selects join points and collects context at those points. AspectJ has a rich pointcut expression language!
  3. Advice – Code to be executed at a join point that has been selected by a pointcut.

To me, I found it easier to understand these terms if I consider join point as event generated point in code, pointcut as a way to define what events to be captured and advice as event handler.

AOP is indeed a powerful way to factor out system or infrasturcture-related code from the business oriented code. Typically, we use it to take care of transaction, security and profiling aspects. But it doesn’t stop you putting creativity in this domain. With a bit more creativity, you can also do the following::

  1. Exception translation – checked to runtime
  2. Catch ConcurrencyFailureExceptions and transparently retry if an idempotent operation fails with, for example, a deadlock loser exception.

How I use Spring AOP in my project?

I have been told to report the elapsed time for all calls to the database. If I don’t know how to use AOP, I may end up putting code to measure time for every JDBC calls. It ends up tangling performance monitoring code with my main line business logic and the same logic will be scattered everywhere in my data access code. Bad!! That is why we need to know how to factor out the performance monitoring code into an aspect like below:

Here we use AspectJ annotation approach to implement the aspect. “Around” is to intercept start and end of any repository method. Here is what states in Spring 2.5 reference:

Spring 2.0 introduces a simpler and more powerful way of writing custom aspects using either a schema-based approach or the @AspectJ annotation style. Both of these styles offer fully typed advice and use of the AspectJ pointcut language, while still using Spring AOP for weaving.

If you use AspectJ annotation, you need to put <aop:aspectj-autoproxy/> in your application-context.xml. The limitation of Spring proxy-based AOP is that it is limited to method invocation interception. To get around that, you can use AspectJ syntax in your pointcut expression. You don’t need to build the application with ajc (the AspectJ compiler) even you are using AspectJ syntax. Spring AOP can also understand @AspectJ aspects. I strong suggest you use Annotation driven AOP because it is cleaner and simplier. Working with AOP, I have faced 2 questions.

  1. How to select the methods that I want to intercept without hardcoding the method or package name in my pointcut expression. So, my aspect or pointcut doesn’t contain application specific information – Look into annotation and AOP section.
  2. How to turn on and off AOP without restarting the web application? I would use JMX. Look into “What is JMX” section. 

Annotation and AOP

Annotation provides a better way other than code signature for selecting join point that leads to creating loosely coupled aspect. In fact, you can see annotation as another signature of a method in other dimension. And a method can have multiple annotations and each concern just bother its own annotation. It is called multidimensional signature space. For example,

@Authentication(“bankOperation”)
@Transactional(REQUIRED)
public void credit(){…}

Pointcut uses annotation to capture join points. For example:

execution(@Transactional * *.*(..)) Execution of a method annotated as Transactional
execution((@Trasactional *) *.*(..)) Execution of a method that returns object annotated as Transactional
execution(* (@Transactional *).*(..)) Execution of a method defined for type annotated as Transactional

Selection can use Annotation types and Annotation values.  What is more, annotation values can be used in Advice implementation.

Here is a great video from Parleys that talked about “Leveraging Annotation with AOP”. I have included some key points Ramnivas made here:

  • Write you pointcut in a smart way to avoid annotation mess. Try to use naming and package convention to help you. For example, if you want to write app log for all public facing service method, you can use “public” with package name containing “service” wildcard to help you.
  • If you really need to use annotation like @Transaction that designer has no way to define the pointcut beforehand, use annotation to describe what the join point is but not how to handle it. So, your transaction aspect only need to worry annotation @Transaction and decouple from the application.
  • You can piggyback annotation. For example, you can make all entities auditable via declare @type: @Entity *: @Auditable; 

How does Spring AOP work internally?

The magic behind AOP is the concept of Proxy/ Decorator/ Interceptor/ Filter pattern. To me, all those patterns are conceptually the same. They all try to present itself as target object (thru implementing the same interface), intercept method call and execute injected logics. And you can have more than one interceptors invoked in series. In Spring AOP, there is one thing we need to pay attention:

However, once the call has finally reached the target object, …any method calls that it may make on itself, such as this.bar() or this.foo(), are going to be invoked against the this reference, and not the proxy. This has important implications. It means that self-invocation is not going to result in the advice associated with a method invocation getting a chance to execute. To handle this, either you refactor your code such that the self-invocation does not happen (best approach) or you make self invocation call thru proxy like ((Pojo) AopContext.currentProxy()).bar() (invasive approach b/c it totally couples your code to Spring AOP, and it makes the class itself aware of the fact that it is being used in an AOP context, which flies in the face of AOP. Avoid using it).

However, it must be noted that AspectJ does not have this self-invocation issue because it is not a proxy-based AOP framework.

What is JMX?

In short, it is a way to enable management and monitoring of Java applications over a generic API. JMX has a simple architecture that contains instrumentation level, agent level and distribution service level. In instrumentation layer, we register MBean to the MBeanServer. In simple term, In simple term, MBean is a  JavaBean with defined management interface that exposes attributes and operations to the world. MBeanServer acts as a broker to decouple communication among application MBeans and/or remote clients.

Combine AOP and JMX

AOP is statically defined and intercept at the runtime. It is hard to take this out or add another aspect in after you start your machine. However, with JMX, you can enable and disable it via skipping the aspect code. :cool: On the other hand, you can also use JMX to configure and report SLA metrics like configure thresholds and send notifications of violations. That sounds very interesting to me. There are other interesting usages mentioned in the Parley’s video as well:

  1. Service blocking – throw an exception if particular service you don’t want to user to use it for a period of time esp during maintenance time.
  2. Caching management – I am currently using interceptor pattern and IoC to intercept dao method calls for cache lookup. 

Reference

  1. JavaOne 07 – JMX, AOP and Spring (Nice Presentation)
  2. Parley’s AOP and JMX (Video)
  3. Simplifying Enterprise Applications with Spring 2.0 and AspectJ
  4. Workflow Orchestration Using AOP
  5. Performance Monitoring with AOP and JMX

 

Leave a comment Continue Reading →

Hibernate vs iBatis

Hibernate is great. However, I don’t see it fits all the data access requirements. At its core, it is an ORM tool that helps you to map your object model to relational model. If you have full control of your relational model and perform lots of CRUD operations, it is certainly a great tool for you. Its transparent persistence, 2 level caching, dirty checking, lazy/ eager data retrieval and sql generation indeed can save us lots of development time. However, one tool doesn’t fit all !! Why not?

In my current company, I have created a reporting tool that interfaces with dimensional model in data warehouse. In this setting, you will deal with star schema with denormalized dimensions.  Often time, I need to tune the query performance via looking into explain plan. Without full control of SQL, my job will be hard to achieve. Apart from that, reporting tool often issues read-only set based queries to the data warehouse. The resultset returned doesn’t fit into my OO model at all. Again, Hibernate just doesn’t fit in. People in my company argue that I should use named query in Hibernate for the sake of sticking with the standard. I am like ok, whatever… I have known a tool called iBatis that I can achieve my job cleanly. Why the hell I would have motivation to try named query that basically a way to by-pass the ORM model to query database. What benefit I will get from this? The cache? We are using ETL to update our fact and dimension in the data warehouse, not by my reporting app. Unless the ETL throws me an event when the update cycle is finished so I can flush my cache, I simply don’t think it gives me lots of help.

Anyway, it is just my own little perspective. You don’t have to agree with me. The point here is not that I don’t like Hibernate but I don’t like to be pushed to use it only because it is “standard” to someone. If Hibernate could help me to construct my sql based on user input, stream my result directly to my presentation layer, populate my model automatically based on mapping I provided, detect data warehouse changes and take care my cache, then I am more happy to adopt it in my reporting app. Otherwise, I would not be eager to dump my iBatis DAO layer unless I get no choice under the political game.

Reference

  1. http://www.nofluffjuststuff.com/media.jsp?id=19
  2. http://www.javalobby.org/articles/hibernate-query-101/
  3. How to use named parameters and named query in Hibernate?
  4. Don’t repeat your DAO 
Leave a comment Continue Reading →

Concurrent Programming

Blocking Queue

Behavior

Quite often in threaded applications we have a producer-consumer situation where some threads want to add jobs onto a queue, and some other worker threads want to remove jobs from the queue and then execute them. It is quite useful in such circumstances to write a queue which blocks on pop when there is nothing on the queue. Otherwise the consumers would have to poll, and polling is not very good because it wastes CPU cycles. When clients attempt to retrieve elements but none are available, a BlockingQueue encapsulates code that waits until an element becomes available.

Usage

The server runs infinitely, accepting requests from a client. Clients can send requests asynchronously and rapidly—the server only adds a client request to the server’s queue (ie. blocking queue), then returns immediately to the client. A separate server thread loops indefinitely, asking the BlockingQueue to return when a new request becomes available. Once a request is available, it’s removed from the queue. The server then handles the request.

Reference

  1. Java Specialist – Blocking Queue

 

ReentrantLock

Behavior

ReentrantLock supports all of the lock-acquisition modes defined by Lock, providing more flexibility for dealing with lock unavailability than does synchronized. Intrinsic locking (ie. synchronized) works fine in most situations but has some functional limitations: It is not possible to interrupt a thread waiting to acquire a lock. If you want the lock, you need to prepare to wait for it forever. Using ReentrantLock, you have more flexibility and scalability:

  1. Timed and Polled lock acquisition – Use tryLock(). One form of this method returns immediately if the lock is already held and the other can wait for some period of time for the lock to become available before giving up. In both cases, we could effectively loop and retry the tryLock() until it succeeds.
  2. Interruptable lock acquisition – Use lockInterruptabily() allows locking to be used within cancellable activities
  3. Non-block structured locking

Usage

Reference

  1. Choosing between synchronized and ReentrantLock
  2. More flexible, scalable locking in JDK 5 – Brian Goetz

 


Leave a comment Continue Reading →

Concurrent Programming – Part 1 Synchronization

Get yourself familiar with concurrency programming

When I interview my candidates, I like to ask questions related to multi-threading. I found out that it is a good topic to differentiate out a hardcore programmer from application-oriented programmer. I am not saying I am looking for someone who could write the concurrency library as efficient as the one created by Doug Lea. In fact, I am looking for candidates who has solid understanding of this topic. However, I found out that most candidates have little knowledge in this area apart from the meaning of “synchronized” keyword in Java syntax. Therefore I decide to write a series of articles to cover some areas of multi-threading that I feel important to understand. Of course, I would start from the basic first.

Introduction of Synchronization

Synchronization is a way to lock an object, so no 2 threads possibly running on the same code at the same time.

public class SynchronizedCounter {
    private double c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }

    public void method2() {
        ...
    }
}

If count is an instance of SynchronizedCounter, then making these methods synchronized has two effects:

  • Mutual Exclusion – It is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object. Remember this rule doesn’t apply to non-synchronized methods. And the thread holds the lock of the object can reenter its synchronized methods (ie. reentrance).
  • Memory-Visibility – When a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads. Most of the interviewers miss this one. :smile: In database, it is like the concept of “commit”. If you don’t commit your changes, others could not see your changes.

All in all, synchronized methods enable a simple strategy for preventing thread interference and memory consistency errors. Interference happens when two operations, running in different threads, but acting on the same data, interleave. This means that the two operations consist of multiple steps, and the sequences of steps overlap. This will result in unpredictable data lost (hard to fix). Memory consistency error occurs when complier and processor reorder statements and uses the cached value for better performance

Problem of Synchronization

Synchronization will serialize the method calls from different threads. At any given time, only one thread can execute the synchronized method and the other threads need to wait until the object lock releases. This will dramatically diminish the liveness of your application. To minimize the impact, you should:

  1. Reduce lock duration – Synchronized statements are useful for improving concurrency with fine-grained synchronization
  2. Reduce lock scope – Mutex variable in the synchronized lock may help you to avoid locking the whole object. In Java 5 concurrency library, there is class called ReentrantLock that provides the same features as synchronized with better performance and flexibility. Here is what is stated in “Java Concurrency in Practice”:

Why create a new locking mechanism (ie. ReentrantLock) that is so similar to intrinsic locking (ie. synchronized)? Intrinsic locking works fine in most situations but has some functional limitations. It is not possible to interrupt a thread waiting to acquire a lock, or to attempt to acquire a lock without being willing to wait for it forever. Intrinsic locks also must be released in the same block of code in which they are acquired; this simplifies coding and interacts nicely with exception handling, but makes non-block structured locking disciplines impossible. None of these are reasons to abandon synchronized, but in some cases a more flexible locking mechanism offers better liveness or performance.

So far so good.? Great! lets me ask you 3 questions:

  1. Question 1: In the example above, if thread A is executing a synchronized method “increment”, can another thread execute method2? Yes. Because method2 is not synchronized
  2. Question 2: If thread A is in the synchronized method xyz , can it invoke another synchronized abc? Yes. The object lock is reentrant.
  3. Question 3: If I want to make the above class thread-safe without using synchronized object lock, are there any other alternatives? Yes.
  4. Question 4: How about declare the variable volatile?
    • Managing Volatility by Brian Goetz
    • Compare Atomic variable, ReentrantLock and Volatile variable.
    • Use int, byte instead of long or double because updating int or byte is an atomic action. Atomic actions cannot be interleaved, so they can be used without fear of thread interference. However, this does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible (for example, thread A updated an variable atomically but it hasn’t flushed and sync up the main memory, so it is not visible to other threads). Unless the fields in question are declared [code]]czoxMDpcInZvbGF0aWxlLCBcIjt7WyYqJl19[[/code] the JMM does not require the underlying platform to provide cache coherency or sequential consistency across processors, so it is possible, on some platforms, to read stale data in the absence of synchronization. Look at here for better explanation. However, volatile can only guarantee atomicity and memory consistency for single variable. If you want to guarantee that for compound operations, you need to use synchronized block.(or the new java.util.concurrent classes). It is worth pointing out that increment (i.e. ++) and similar operations are not atomic in Java. So incrementing a volatile variable [code]]czoxMzpcInZvbGF0aWxlVmFyKytcIjt7WyYqJl19[[/code] is NOT thread-safe. If you need thread-safe semantics i.e. no possibility of multiple threads corrupting the variable value by having the updates unexpectedly interfere with each other, then you need to use a synchronized block to increment a variable, e.g. [code]]czoyNzpcInN5bmNocm9uaXplZChMT0NLKXtteVZhcisrfVwiO3tbJiomXX0=[[/code], regardless of the overheads this causes – Java Performance Tuning

More On Thread Safety

All the techniques I discussed so far is to show you how to make your code thread safe. They are applicable only if you have to share resources across multiple threads and those threads may modify the resources. That is to say, if you don’t share any resources or other threads only read but no write, your code are thread safe already. Here are some tips related to not sharing and read-only sharing:

  1. You can use local variables to carry out logic in the methods if possible (not share)
  2. You can use TheadLocal to hold the resources if you want to access it across multiple methods for the same thread (not share)
  3. You can use immutable object (private variable without setXXX methods) for read-only sharing. For example, String and PrimitiveWrappers like Integer. However, make sure the declare final for the reference that holds your immutable object.
  4. Most of the time, you use collection classes like HashMap, ArrayList to hold our objects. Those classes are not thread safe. To make it thread safe, you may use Collections.synchronized wrappers or simply use the synchronized version of them like Hashtable and Vector. However, these approaches have 2 problems
    • They are not performed. Why lock every reads only to protect occasional write?
    • They are just conditionally thread-safe. All individual operations are thread-safe, but sequences of operations where the control flow depends on the results of previous operations may be subject to data races like doing containsKey(), size() and iterator() methods before actually read and write can give you NullPointerException and ConcurrentModificationException if you don’t do external synchronization.
    • Here are the unconditionally thread-safe version like ConcurrentHashMap, ConcurrentLinkedQueue and CopyOnWriteArrayList to achieve thread-safe with good performance number.
    • When you write an unconditionally thread-safe class, consider using private lock object in place of synchronized methods. This protect you against synchronization interference by clients and subclasses and gives you the flexibility to adopt a more sophisticated approach to concurrent control in later release – Joshua Bloch in Effective Java 2nd version p.281.
  5. Deal with lazy initialization
  6. Handle denial of service attack that holds the object lock forever

Java Memory Model

JMM is what causes concurrent programming way more complicated than it should be. Honestly, I am not good to write this part because I cannot understand it in full. All I can do is to provide you a video from Jeremy Manson in Google. Hear what the expert said:

 If you still have questions, make sure go to his blog

http://jeremymanson.blogspot.com/

Reference

Below are some of the articles I use:

  1. What does volatile do?
  2. Sun lesson on concurrency
  3. Fixing Java Memory Model – Brian Goetz – Part 1, Part 2
  4. Rox Java NIO Tutorial
  5. Blocking Queue
  6. Synchronization and Java Memory Model – Doug Lea 

 

Leave a comment Continue Reading →