Tuesday, April 14, 2015

Configure a Spring JMS application with Spring Boot and annotation support

1   Introduction


In previous posts we learned how to configure a project using Spring JMS. If you check the article introduction to messaging with Spring JMS, you will notice that it is configured using XML. This article will take advantage of the improvements introduced in Spring 4.1 version, and configure a JMS project using Java config only.

In this example we will also see how easy it can be to configure the project by using Spring Boot.

Before we get started, just note that as usual, you can take a look at the source code of the project used in the examples below.

See the example project at github.

Sections:
  1. Introduction.
  2. The example application.
  3. Setting up the project.
  4. A simple example with JMS listener.
  5. Sending a response to another queue with @SendTo.
  6. Conclusion.

2   The example application


The application uses a Client service to send orders to a JMS queue, where a JMS listener will be registered and handle these orders. Once received, the listener will store the order through the Store service:



We will use the Order class to create orders:

Before moving on to the first example, we will first explore how the project structure is built.


3   Setting up the project


3.1   Configuring pom.xml

The first thing to do is to define the artifact spring-boot-starter-parent as our parent pom.

This parent basically sets several Maven defaults and provides the dependency management for the main dependencies that we will use, like the Spring version (which is 4.1.6).

It is important to note that this parent pom defines the version of many libraries but it does not add any dependency to our project. So don’t worry about getting libraries you won’t use.

The next step is to set the basic dependencies for Spring Boot:

In addition to the core Spring libraries, this dependency will bring the auto configuration functionality of Spring Boot. This will allow the framework to try to automatically set up the configuration based on the dependencies you add.

Finally, we will add the Spring JMS dependency and the ActiveMQ message broker, leaving the whole pom.xml as follows:

3.2   Spring Configuration with Java Config

We used @SpringBootApplication instead of the usual @Configuration annotation. This Spring Boot annotation is also annotated with @Configuration. In addition, it sets other configuration like Spring Boot auto configuration:

The configuration class does not need to define any bean. All the configuration is automatically set by Spring Boot. Regarding the connection factory, Spring Boot will detect that I included the ActiveMQ dependency on the classpath and will start and configure an embedded broker.

If you need to specify a different broker url, you can declare it in the properties. Check ActiveMQ support section for further detail.

It is all set now. We will see how to configure a JMS listener in the example in the next section, since it is configured with an annotation.


4   A simple example with JMS listener


4.1   Sending an order to a JMS queue

The ClientService class is responsible for sending a new order to the JMS queue. In order to accomplish this, it uses a JmsTemplate:

Here, we use a JmsTemplate to convert our Order instance and send it to the JMS queue. If you prefer to directly send a message through the send message, you can instead use the new JmsMessagingTemplate. This is preferable since it uses the more standardized Message class.


4.2   Receiving an order sent to the JMS queue

Registering a JMS listener to a JMS listener container is as simple as adding the @JmsListener annotation to the method we want to use. This will create a JMS listener container under the covers that will receive messages sent to the specified queue and delegate them to our listener class:

The StoreService receives the order and saves it to a list of received orders:

4.3   Testing the application

Now let’s add a test to check if we did everything correctly:


5   Sending a response to another queue with @SendTo


Another addition to Spring JMS is the @SendTo annotation. This annotation allows a listener to send a message to another queue. For example, the following listener receives an order from the “in.queue” and after storing the order, sends a confirmation to the “out.queue”.

There, we have another listener registered that will process this confirmation id:


6   Conclusion


With annotation support, it is now much easier to configure a Spring JMS application, taking advantage of asynchronous message retrieval using annotated JMS listeners.

I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.

Sunday, March 8, 2015

Improving performance: non-blocking processing of streams

1   Introduction

Imagine we have an application that needs to access an external web service in order to gather information about clients and then process it. More specifically, we can’t get all this information in a single invocation. If we want to look up different clients, we will need several invocations.

As shown in the graphic below, the example application will retrieve information about several clients, group them in a list and then process it to calculate the total amount of its purchases:


In this post, we will see different ways of gathering the information and which one is the best in terms of performance.

This is a Java related post. However, we will use the Spring framework to invoke a RESTful web service.

Sections:
  1. Introduction
  2. Explaining the example
  3. First attempt: Sequential stream
  4. Improving performance: Parallel stream
  5. Non-blocking processing with CompletableFuture
  6. Conclusion

The source code can be found at the Java 8 GitHub repository.

Additionally, you can access the source code of the web application exposing the RESTful web service at this repository.


2   Explaining the example

In our application, we have a list of 20 ids representing clients we want to retrieve from a web service. After retrieving all the clients, we will look up at what did every client purchase and sum them up to compute what is the total amount of money spent by all the clients.

There is one problem though, this web service only allows to retrieve one client at each invocation, so we will need to invoke the service twenty times. In addition, the web service is a little bit slow, taking at least two seconds to respond to a request.

If we take a look at the application implementing the web service, we can see that invocations are handled by the ClientController class:

A Thread.sleep is used to simulate the slowness in responding.

The domain class (Client) contains the information we need; how much money has a client spent:


3   First attempt: Sequential stream

In this first example we will sequentially invoke the service to get the information of all twenty clients:

Output:
Sequential | Total time: 42284 ms
Total purchases: 20.0

The execution of this program takes 42 seconds approximately. This is too much time. Let’s see if we can improve its performance.


4   Improving performance: Parallel stream

Java 8 allows us to split a stream into chunks and process each one in a separate thread. What we need to do is simply create the stream in the previous example as a parallel stream.

You should take into account that each chunk will be executed in its thread asynchronously, so the order in which the chunks are processed must not matter. In our case, we are summing the purchases, so we can do it.

Let’s try this:

Output:
Parallel | Total time: 6336 ms
Total purchases: 20.0

Wow, that’s a big improvement! But what does this number come from?

Parallel streams internally use the ForkJoinPool, which is the pool used by the ForkJoin framework introduced in Java 7. By default, the pool uses as many threads as your machine's processors can handle. My laptop is a quad core that can handle 8 threads (you can check this by invoking Runtime.getRuntime.availableProcessors), so it can make 8 invocations to the web service in parallel. Since we need 20 invocations, it will need at least 3 "rounds":


Ok, so from 40 seconds to 6 is quite a good improvement but, can we still improve it further? The answer is yes.


5   Non-blocking processing with CompletableFuture

Let’s analise the previous solution.

We send 8 threads invoking each one the web service, but while the service is processing the request (two whole seconds), our processors are doing nothing but waiting (this is a IO operation). Until these requests don’t come back, we won’t be able to send more requests.

The question is, what if we could send all 20 requests asynchronously, freeing our processors and process each response when is available? This is where CompletableFuture comes to the rescue:

Output:
Async with executor | Total time: 2192 ms
Total purchases: 20.0

It took a third of the time spent in the previous example.

We sent all 20 requests at the same time, so the time spent in IO operations is spent only once. As soon as responses come by, we process them quickly.

It is important the use of the executor service, set as an optional second parameter of the supplyAsync method. We specified a pool of a hundred threads so we could send 100 requests at the same time. If we don’t specify an executor, the ForkJoin pool will be used by default.

You can try to remove the executor and you will see the same performance as in the parallel example.


6   Conclusion

We have seen that when executing operations that do not involve computing (like IO operations) we can use the CompletableFuture class to take advantage of our processors and improve the performance of our applications.

I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.

Sunday, February 15, 2015

Java Concurrency Tutorial - Locking: Explicit locks

1   Introduction


In many cases, using implicit locking is enough. Other times, we will need more complex functionalities. In such cases, java.util.concurrent.locks package provides us with lock objects. When it comes to memory synchronization, the internal mechanism of these locks is the same as with implicit locks. The difference is that explicit locks offer additional features.

The main advantages or improvements over implicit synchronization are:

  • Separation of locks by read or write.
  • Some locks allow concurrent access to a shared resource (ReadWriteLock).
  • Different ways of acquiring a lock:
    • Blocking: lock()
    • Non-blocking: tryLock()
    • Interruptible: lockInterruptibly()


2   Classification of lock objects


Lock objects implement one of the following two interfaces:

  • Lock: Defines the basic functionalities that a lock object must implement. Basically, this means acquiring and releasing the lock. In contrast to implicit locks, this one allows the acquisition of a lock in a non-blocking or interruptible way (additionally to the blocking way). Main implementations:
    • ReentrantLock
    • ReadLock (used by ReentrantReadWriteLock)
    • WriteLock (used by ReentrantReadWriteLock)

  • ReadWriteLock: It keeps a pair of locks, one for read-only operations and another one for writing. The read lock can be acquired simultaneously by different reader threads (as long as the resource isn’t already acquired by a write lock), while the write lock is exclusive. In this way, we can have several threads reading the resource concurrently as long as there is not a writing operation. Main implementations:
    • ReentrantReadWriteLock

The following class diagram shows the relation among the different lock classes:



3   ReentrantLock


This lock works the same way as the synchronized block; one thread acquires the lock as long as it is not already acquired by another thread, and it does not release it until unlock is invoked. If the lock is already acquired by another thread, then the thread trying to acquire it becomes blocked until the other thread releases it.

We are going to start with a simple example without locking, and then we will add a reentrant lock to see how it works.

Since the code above is not synchronized, threads will be interleaved. Let’s see the output:

Thread-2 - 1
Thread-1 - 1
Thread-1 - 2
Thread-1 - 3
Thread-2 - 2
Thread-2 - 3

Now, we will add a reentrant lock in order to serialize the access to the run method:

The above code will safely be executed without threads being interleaved. You may realize that we could have used a synchronized block and the effect would be the same. The question that arises now is what advantages does the reentrant lock provides us?

The main advantages of using this type of lock are described below:

  • Additional ways of acquiring the lock are provided by implementing Lock interface:
    • lockInterruptibly: The current thread will try to acquire de lock and become blocked if another thread owns the lock, like with the lock() method. However, if another thread interrupts the current thread, the acquisition will be cancelled.
    • tryLock: It will try to acquire the lock and return immediately, regardless of the lock status. This will prevent the current thread from being blocked if the lock is already acquired by another thread. You can also set the time the current thread will wait before returning (we will see an example of this).
    • newCondition: Allows the thread which owns the lock to wait for a specified condition.

  • Additional methods provided by the ReentrantLock class, primarily for monitoring or testing. For example, getHoldCount or isHeldByCurrentThread methods.


Let’s look at an example using tryLock before moving on to the next lock class.


3.1   Trying lock acquisition


In the following example, we have got two threads, trying to acquire the same two locks.

One thread acquires lock2 and then it blocks trying to acquire lock1:

Another thread, acquires lock1 and then it tries to acquire lock2.

Using the standard lock method, this would cause a dead lock, since each thread would be waiting forever for the other to release the lock. However, this time we are trying to acquire it with tryLock specifying a timeout. If it doesn’t succeed after four seconds, it will cancel the action and release the first lock. This will allow the other thread to unblock and acquire both locks.

Let’s see the full example:

If we execute the code it will result in the following output:

13:06:38,654|Thread-2|Trying to acquire lock2...
13:06:38,654|Thread-1|Trying to acquire lock1...
13:06:38,655|Thread-2|Lock2 acquired. Trying to acquire lock1...
13:06:38,655|Thread-1|Lock1 acquired. Trying to acquire lock2...
13:06:42,658|Thread-1|Failed acquiring lock2. Releasing lock1
13:06:42,658|Thread-2|Both locks acquired

After the fourth line, each thread has acquired one lock and is blocked trying to acquire the other lock. At the next line, you can notice the four second lapse. Since we reached the timeout, the first thread fails to acquire the lock and releases the one it had already acquired, allowing the second thread to continue.


4   ReentrantReadWriteLock


This type of lock keeps a pair of internal locks (a ReadLock and a WriteLock). As explained with the interface, this lock allows several threads to read from the resource concurrently. This is specially convenient when having  a resource that has frequent reads but few writes. As long as there isn’t a thread that needs to write, the resource will be concurrently accessed.

The following example shows three threads concurrently reading from a shared resource. When a fourth thread needs to write, it will exclusively lock the resource, preventing reading threads from accessing it while it is writing. Once the write finishes and the lock is released, all reader threads will continue to access the resource concurrently:

The console output shows the result:

11:55:01,632|pool-1-thread-1|Read lock acquired
11:55:01,632|pool-1-thread-2|Read lock acquired
11:55:01,632|pool-1-thread-3|Read lock acquired
11:55:04,633|pool-1-thread-3|Reading data: default value
11:55:04,633|pool-1-thread-1|Reading data: default value
11:55:04,633|pool-1-thread-2|Reading data: default value
11:55:04,634|pool-1-thread-4|Write lock acquired
11:55:07,634|pool-1-thread-4|Writing data: changed value
11:55:07,634|pool-1-thread-3|Read lock acquired
11:55:07,635|pool-1-thread-1|Read lock acquired
11:55:07,635|pool-1-thread-2|Read lock acquired
11:55:10,636|pool-1-thread-3|Reading data: changed value
11:55:10,636|pool-1-thread-1|Reading data: changed value
11:55:10,636|pool-1-thread-2|Reading data: changed value

As you can see, when writer thread acquires the write lock (thread-4), no other threads can access the resource.


5   Conclusion


This post shows which are the main implementations of explicit locks and explains some of its improved features with respect to implicit locking.

This post is part of the Java Concurrency Tutorial series. Check here to read the rest of the tutorial.

You can find the source code at Github.

I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.


Monday, December 22, 2014

Exposing HTTP Restful API with Inbound Adapters. Part 2 (Java DSL)

1   Introduction


In the previous part of this tutorial, we implemented an application exposing a Restful API using XML configuration. This part will re-implement this application using Spring Integration Java DSL.

The application is implemented with Java 8, but when Java 8 specific code is used (for example, when using lambdas), I will also show you how to do it in Java 7. Anyway, I shared both versions at Github in case you want to check it out:

Java 7 Java DSL example

Java 8 Java DSL example


This post is divided into the following sections
  1. Introduction
  2. Application configuration
  3. Get operation
  4. Put and post operations
  5. Delete operation
  6. Conclusion


2   Application configuration


In the web.xml file, the dispatcher servlet is configured to use Java Config:

In the pom.xml file, we include the Spring Integration Java DSL dependency:

InfrastructureConfiguration.java

The configuration class contains bean and flow definitions.

In order to parse payload expressions, we define a bean parser, using an SpELExpressionParser.

The header mapper will later be registered as a property of inbound gateways, in order to map HTTP headers from/to message headers.

The detail of the flows and endpoints defined in this configuration class is explained in each of the following sections.


3   Get operation


Our first step is to define the HTTP inbound gateway that will handle GET requests.

The createMapping method is the Java alternative to the request-mapping XML element seen in the previous part of the tutorial. In this case, we can also use it to define the request path and supported methods.

Now that we have our gateway set, let’s define the flow that will serve GET requests (remember you can check a diagram of the full flow in the previous part of the tutorial):

The flow works as follows:
  • from(httpGetGate()): Get messages received by the HTTP Inbound Gateway.
  • channel(“httpGetChannel”): Register a new DirectChannel bean and send the message received to it.
  • handle(“personEndpoint”, “get”): Messages sent to the previous channel will be consumed by our personEndpoint bean, invoking its get method.

Since we are using a gateway, the response of the personEndpoint will be sent back to the client.

I am showing the personEndpoint for convenience, since it’s actually the same as in the XML application:

GetOperationsTest uses a RestTemplate to test the exposed HTTP GET integration flow:

I won’t show the full class since it is the same as in the XML example.


4   Put and post operations


Continuing with our Restful API application example, we define a bean for the HTTP inbound channel adapter.  You may notice that we are creating a new Gateway. The reason is that inbound channel adapter is internally implemented as a gateway that is not expecting a reply.

We are again using the parser to resolve the returned status code expression.

The former XML attribute request-payload-type of the inbound adapter is now set as a property of the gateway.

The flow that handles both PUT and POST operations uses a router to send the message to the appropriate endpoint, depending on the HTTP method received:

The flow is executed the following way:
  • from(httpPostPutGate()):Get messages received by the HTTP Inbound adapter.
  • channel(“routeRequest”): Register a DirectChannel bean and send the message received to it.
  • route(...): Messages sent to the previous channel will be handled by a router, which will redirect them based on the HTTP method received (http_requestMethod header). The destination channel is resolved applying the prefix and suffix. For example, if the HTTP method is PUT, the resolved channel will be httpPutChannel, which is a bean also defined in this configuration class.

Subflows (httpPutFlow and httpPostFlow) will receive messages from the router and handle them in our personEndpoint.

Since we defined an inbound adapter, no response from the endpoint is expected.

In the router definition we used Java 8 lambdas. I told you I would show the alternative in Java 7, so a promise is a promise:

A little bit longer, isn’t it?

The PUT flow is tested by the PutOperationsTest class:

The POST flow is tested by the PostOperationsTest class:


5   Delete operation


With this operation we complete our application. The entry point is defined by the following bean:

The configuration is pretty similar to the PutPost gateway. I won’t explain it again.

The delete flow sends the deletion request to the personEndpoint:

And our bean will request the service to delete the resource:

The test asserts that the resource no longer exists after deletion:


6   Conclusion


This second part of the tutorial has shown us how to implement a Spring Integration application with no XML configuration, using the new Spring Integration Java DSL. Although flow configuration is more readable using Java 8 lambdas, we still have the option to use Java DSL with previous versions of the language.

I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.




Exposing HTTP Restful API with Inbound Adapters. Part 1 (XML)

1   Introduction


The purpose of this post is to implement an HTTP Restful API using Spring Integration HTTP inbound adapters. This tutorial is divided into two parts:

  • XML configuration example (this same post).
  • Java DSL example. This will be explained in the next part of this tutorial, showing how to configure the application using Spring Integration Java DSL, with examples with both Java 7 and Java 8.

Before looking at the code, let’s take a glance at the following diagram, which shows the different services exposed by the application:


GET operations are handled by an HTTP inbound gateway, while the rest (PUT, POST and DELETE) are handled by HTTP inbound channel adapters, since no response body is sent back to the client. Each operation will be explained in the following sections:
  1. Introduction
  2. Application configuration
  3. Get operation
  4. Put and post operations
  5. Delete operation
  6. Conclusion
The source code is available at Github.


2   Application configuration


The web.xml file contains the definition of the Dispatcher Servlet:

The http-inbound-config.xml file will be explained in the following sections.

The pom.xml file is detailed below. It is important to note the jackson libraries. Since we will be using JSON to represent our resources, these libraries must be present in the class path. Otherwise, the framework won’t register the required converter.


3   Get operation


The configuration of the flow is shown below:

http-inbound-config.xml

The gateway receives requests to this path: /persons/{personId}. Once a request has arrived, a message is created and sent to httpGetChannel channel. The gateway will then wait for a service activator (personEndpoint) to return a response:

Now, some points need to be explained:

  • supported-methods: this attribute indicates which methods are supported by the gateway (only GET requests).
  • payload-expression: What we are doing here is getting the value from personId variable in the URI template and putting it in the message’s payload. For example, the request path ‘/persons/3’ will become a Message with a value ‘3’ as its payload.
  • request-mapping: We can include this element to specify several attributes and filter which requests will be mapped to the gateway. In the example, only requests that contain the value ‘application/json’ for Content-Type header (consumes attribute) and Accept header (produces attribute) will be handled by this gateway.

Once a request is mapped to this gateway, a message is built and sent to the service activator. In the example, we defined a simple bean that will get the required information from a service:

Depending on the response received from the service, we will return the requested person or a status code indicating that no person was found.

Now we will test that everything works as expected. First, we define a ClientPerson class to which the response will be converted:

Then we implement the test. The buildHeaders method is where we specify Accept and Content-Type headers. Remember that we restricted requests with ‘application/json’ values in those headers.

Not specifying a correct value in the Content-Type header will result in a 415 Unsupported Media Type error, since the gateway does not support this media type.

On the other hand, specifying an incorrect value in the Accept header will result in a 406 Not Acceptable error, since the gateway is returning another type of content than the expected.


4   Put and post operations


For PUT and POST operations, we are using the same HTTP inbound channel adapter, taking advantage of the possibility to define several paths and methods to it. Once a request arrives, a router will be responsible to delivering the message to the correct endpoint.

http-inbound-config.xml

This channel adapter includes two new attributes:

  • status-code-expression: By default, the channel adapter acknowledges that the request has been received and returns a 200 status code. If we want to override this behavior, we can specify a different status code in this attribute. Here, we specify that these operations will return a 204 No Content status code.
  • request-payload-type: This attribute specifies what class will the request body be converted to. If we do not define it, it will not be able to convert to the class that the service activator is expecting (ServerPerson).


When a request is received, the adapter sends it to the routeRequest channel, where a router is expecting it. This router will inspect the message headers and depending on the value of the ‘http_requestMethod’ header, it will deliver it to the appropriate endpoint.

Both PUT and POST operations are handled by the same bean:

Return type is void because no response is expected; the inbound adapter will handle the return of the status code.

PutOperationsTest validates that the correct status code is returned and that the resource has been updated:

PostOperationsTest validates that the new resource has been added:


5   Delete operation


The last operation of our restful API is the delete operation. This time we use a single channel adapter for this purpose:

The channel adapter lets us define the returning status code and we are using the payload-expression attribute to map the requested personId to the message body. The configuration is a little bit different from  those in previous operations but there’s nothing not already explained here.

The service activator, our person endpoint, will request the person service to delete this resource.

Finally, the required test:


6   Conclusion


This post has been an introduction to our application in order to understand how it is structured from a known point of view (xml configuration). In the next part of this tutorial, we are going to implement this same application using Java DSL. The application will be configured to run with Java 8, but when lambdas are used, I will also show how it can be done with Java 7.

You can read the second part of this tutorial here.

I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.

Monday, September 1, 2014

Java Concurrency Tutorial - Locking: Intrinsic locks

In previous posts we reviewed some of the main risks of sharing data between different threads (like atomicity and visibility) and how to design classes in order to be shared safely (thread-safe designs). In many situations though, we will need to share mutable data, where some threads will write and others will act as readers. It may be the case that you only have one field, independent to others, that needs to be shared between different threads. In this case, you may go with atomic variables. For more complex situations you will need synchronization.


1   The coffee store example


Let’s start with a simple example like a CoffeeStore. This class implements a store where clients can buy coffee. When a client buys coffee, a counter is increased in order to keep track of the number of units sold. The store also registers who was the last client to come to the store.

In the following program, four clients decide to come to the store to get their coffee:

The main thread will wait for all four client threads to finish, using Thread.join(). Once the clients have left, we should obviously count four coffees sold in our store, but you may get unexpected results like the one above:

Mike bought some coffee
Steve bought some coffee
Anna bought some coffee
John bought some coffee
Sold coffee: 3
Last client: Anna
Total time: 3001 ms

We lost one unit of coffee, and also the last client (John) is not the one displayed (Anna). The reason is that since our code is not synchronized, threads interleaved. Our buyCoffee operation should be made atomic.


2   How synchronization works


A synchronized block is an area of code which is guarded by a lock. When a thread enters a synchronized block, it needs to acquire its lock and once acquired, it won’t release it until exiting the block or throwing an exception. In this way, when another thread tries to enter the synchronized block, it won’t be able to acquire its lock until the owner thread releases it. This is the Java mechanism to ensure that only on thread at a given time is executing a synchronized block of code, ensuring the atomicity of all actions within that block.

Ok, so you use a lock to guard a synchronized block, but what is a lock? The answer is that any Java object can be used as a lock, which is called intrinsic lock. We will now see some examples of these locks when using synchronization.


3   Synchronized methods


Synchronized methods are guarded by two types of locks:

  • Synchronized instance methods: The implicit lock is ‘this’, which is the object used to invoke the method. Each instance of this class will use their own lock.
  • Synchronized static methods: The lock is the Class object. All instances of this class will use the same lock.

As usual, this is better seen with some code.

First, we are going to synchronize an instance method. This works as follows: We have one instance of the class shared by two threads (Thread-1 and Thread-2), and another instance used by a third thread (Thread-3):

Since doSomeTask method is synchronized, you would expect that only one thread will execute its code at a given time. But that’s wrong, since it is an instance method; different instances will use a different lock as the output demonstrates:

Thread-1 | Entering method. Current Time: 0 ms
Thread-3 | Entering method. Current Time: 1 ms
Thread-3 | Exiting method
Thread-1 | Exiting method
Thread-2 | Entering method. Current Time: 3001 ms
Thread-2 | Exiting method

Since Thread-1 and Thread-3 use a different instance (and hence, a different lock), they both enter the block at the same time. On the other hand, Thread-2 uses the same instance (and lock) as Thread-1. Therefore, it has to wait until Thread-1 releases the lock.

Now let’s change the method signature and use a static method. StaticMethodExample has the same code except the following line:

If we execute the main method we will get the following output:

Thread-1 | Entering method. Current Time: 0 ms
Thread-1 | Exiting method
Thread-3 | Entering method. Current Time: 3001 ms
Thread-3 | Exiting method
Thread-2 | Entering method. Current Time: 6001 ms
Thread-2 | Exiting method

Since the synchronized method is static, it is guarded by the Class object lock. Despite using different instances, all threads will need to acquire the same lock. Hence, any thread will have to wait for the previous thread to release the lock.


4   Back to the coffee store example


I have now modified the Coffee Store example in order to synchronize its methods. The result is as follows:

Now, if we execute the program, we won’t lose any sale:

Mike bought some coffee
Steve bought some coffee
Anna bought some coffee
John bought some coffee
Sold coffee: 4
Last client: John
Total time: 12005 ms

Perfect! Well, it really is? Now the program’s execution time is 12 seconds.  You sure have noticed a someLongRunningProcess method executing during each sale. It can be an operation which has nothing to do with the sale, but since we synchronized the whole method, now each thread has to wait for it to execute. Could we leave this code out of the synchronized block? Sure! Have a look at synchronized blocks in the next section.


5   Synchronized blocks


The previous section showed us that we may not always need to synchronize the whole method. Since all the synchronized code forces a serialization of all thread executions, we should minimize the length of the synchronized block. In our Coffee store example, we could leave the long running process out of it. In this section’s example, we are going to use synchronized blocks:

In SynchronizedBlockCoffeeStore, we modify the buyCoffee method to exclude the long running process outside of the synchronized block:

In the previous synchronized block, we use ‘this’ as its lock. It’s the same lock as in synchronized instance methods. Beware of using another lock, since we are using this lock in other methods of this class (countSoldCoffees and getLastClient).

Let’s see the result of executing the modified program:

Mike bought some coffee
John bought some coffee
Anna bought some coffee
Steve bought some coffee
Sold coffee: 4
Last client: Steve
Total time: 3015 ms

We have significantly reduced the duration of the program while keeping the code synchronized.


6   Using private locks


The previous section used a lock on the instance object, but you can use any object as its lock. In this section we are going to use a private lock and see what the risk is of using it.

In PrivateLockExample, we have a synchronized block guarded by a private lock (myLock):

If one thread enters executeTask method will acquire myLock lock. Any other thread entering other methods within this class guarded by the same myLock lock, will have to wait in order to acquire it.

But now, let’s imagine that someone wants to extend this class in order to add its own methods, and these methods also need to be synchronized because need to use the same shared data. Since the lock is private in the base class, the extended class won’t have access to it. If the extended class synchronizes its methods, they will be guarded by ‘this’. In other words, it will use another lock.

MyPrivateLockExample extends the previous class and adds its own synchronized method executeAnotherTask:

The program uses two worker threads that will execute executeTask and executeAnotherTask respectively. The output shows how threads are interleaved since they are not using the same lock:

executeTask - Entering...
executeAnotherTask - Entering...
executeAnotherTask - Exiting...
executeTask - Exiting...


7   Conclusion


We have reviewed the use of intrinsic locks by using Java’s built-in locking mechanism. The main concern here is that synchronized blocks that need to use shared data; have to use the same lock.

This post is part of the Java Concurrency Tutorial series. Check here to read the rest of the tutorial.

You can find the source code at Github.

I'm publishing my new posts on Google plus and Twitter. Follow me if you want to be updated with new content.



Java Concurrency Tutorial

This tutorial consists of several posts that explain the main concepts of concurrency in Java. It starts with the basics with posts about the main concerns or risks of using non-synchronized programs, and it then continues with more specific features.


Basics


Atomicity and race conditions
Atomicity is one of the main concerns in concurrent programs. This post shows the effects of executing compound actions in non-synchronized code.

Visibility between threads
Another of the risks of executing code concurrently is how values written by one thread can become visible to other threads accessing the same data.

Thread-safe designs
After looking at the main risks of sharing data, this post describes several class designs that can be shared safely between different threads.


Synchronization


Locking - Intrinsic locks
Intrinsic locks are Java's built-in mechanism for locking in order to ensure that compound actions within a synchronized block are atomic and create a happens-before relationship.

Locking - Explicit locks
Explicit locks provide additional features to the Java synchronization mechanism. Here, we take a look at the main implementations and how they work.