Skip to main content

Java Keywords (Part XXIV): native

Java keyword list abstract continue for new switch assert default goto * package synchronized boolean do if private this break double implements protected throw byte else import public throws case enum instanceof return transient catch extends int short try char final interface static void class finally long strictfp volatile const * float native super while Keyword marked with an asterisk (*) are keywords that, although valid, are not used by programmers. This is the last chapter of the Java Keyword series. This is probably the keyword I have used the least. In my 20 year career as a software developer, I have used this keyword once, and that was to make some addition to legacy code. The keyword native is a method modifier . Basically, it is a keyword that can only be applied to methods. According to the Java Language Specification (JLS), A method that is native is implemented i...

Java Keywords (Part XXI): synchronized

Java keyword list

abstract continue for new switch
assert default goto* package synchronized
boolean do if private this
break double implements protected throw
byte else import public throws
case enum instanceof return transient
catch extends int short try
char final interface static void
class finally long strictfp volatile
const* float native super while
Keyword marked with an asterisk (*) are keywords that, although valid, are not used by programmers.
Before diving into the use of the synchronized keyword, we must understand concurrency. I will do my best to summarize the concept of concurrency first and then provide use cases for using synchronization.

What is concurrency?

The dictionary definition of the word concurrent is "occurring, arising, or operating at the same time." In computing, this means that a certain operation, or group of operations, must be executed at the same time. In modern computing, this is often taken for granted. I am old enough to remember the old days where you could only execute one program at a time. So, if you wanted to execute a second program, you had to terminate the first before attempting to run the second. Even programs like Microsoft Word had to abide by these rules: If you wanted to open a second document, you had to close the first. Eventually, CPUs went from single core, to dual, to quad, etc., giving us the ability to execute programs "simultaneously." Notice how the word simultaneously was purposely enclosed in quotes. Please do not mistake "concurrency" with "parallelism." Concurrency is the task of running and managing (mainly managing) the multiple computations at the same time. While parallelism is the task of running multiple computations simultaneously. With concurrent processing, the Operating System takes on the task of executing programs simultaneously, but at any given instance of time it's actively working on one specific task.

Take for example the following use case. A person opens Microsoft Word and starts editing 3 documents for a task at work. At any given moment, the person is actively editing one document while the other two are minimized. The person switches between document until all three documents are properly edited. The person edited those documents concurrently, not in parallel. I hope that clarifies the difference between concurrent and parallel processing. Regardless, synchronization is extremely important for both concurrent and parallel processing.

What is synchronization?

Synchronization means the act of being synchronous. That's not very helpful if you don't understand synchronicity. Synchronous means "happening, existing, or arising at precisely the same time." You often see hear in movies "let's synchronize our watches." When they do this, they set the time on their watches to the exact same value, down to the millisecond. Synchronization involves precision. One millisecond off, and you are no longer synchronized. This is the same in computing.

Suppose you write code that reads from and writes to a file. Your application is multi-threaded because different users may decide to read or write to files at different points in time. While you may need to support many simultaneous users, what happens if all your concurrent users need to access the same file at the same time? This is not necessarily a problem if they all need to read the file, but what happens if one decides to write to the file? What happens first? What if two or more decide to write to the file? Will one user overwrite inadvertently what another user wrote? If these actions are not correctly handled, this can be a huge mess. To avoid this mess, as programmers, we need to establish some kind of control for code that can be executed concurrently. The keyword synchronized helps with, but does not fix, concurrency issues.

This article will not get into why or when synchronize is needed. That is a very long and complicated topic. It will simply show you how to use this keyword. To learn more about concurrent programming in Java, please visit The Java™ Tutorials Lesson: Concurrency.

Using the synchronized keyword

The best strategy for using the synchronized keyword is to limit the scope of the synchronized block to the smallest size possible. This means you can synchronize a single line of code inside a function. This is known as a synchronized statement.

public void someMethod() {
    // step 1
    // step 2
    // step 3
    // synchronized statement
    synchronized (...) {
        // step 4
    }
    // step 5
}
or simply synchronize the entire method

public synchronized void someMethod() {
    // code omitted
}

What goes inside the parentheses of the synchronized block?

Remember the example of the synchronized statement?

synchronized (...) {
    // step 4
}
What goes in the place of the ellipsis (...)?

Intrinsic Locks

Unlike synchronized methods, synchronized statements must specify the object that provides the intrinsic lock. Synchronization is built around an internal entity known as the intrinsic lock. Every object has one. What that means for this topic is that you can place any object instance in place of the ellipsis (within reason). Before I continue, I must point out the obvious. Synchronized methods did not have an object serving as the intrinsic lock, or did they? As a matter of fact, they do have an instrinsic lock. In the case of synchronized methods, the object containing the method is the instrinsic lock. In other words, the intrinsic lock is the object itself (this). The only difference is that you do not set it explicitly. It is implicit. In the case of synchronized statements, you could pass this, or you can pass an instance of another object serving as the lock. A word of caution, Java recommends not to use String or any of the other primitive type wrapper classes, like Integer, Long, and others. You can also place (this) as the lock.

synchronized (this) {
    // step 4
}
Let's summarize. The Java programming language provides two basic synchronization idioms: synchronized methods and synchronized statements. The keyword synchronized is used for both. In the case of synchronized methods, the keyword synchronized is placed immediately after the access modifier. In the case of synchronized statements, you must provide an intrinsic lock object; either this or some other instance of an object that will be served as the lock.

To learn more about concurrency in Java, click on the link I previously provided. To learn mora about using synchronized keyword, visit Synchronized Methods and Intrinsic Locks and Synchronization to learn more about synchronized statements.

That is all for this article. I hope it was useful to you. See you next time! Next up, Part XXII: volatile

Comments

Popular posts from this blog

Implementing Interfaces with Java Records

If you have not read my article on Java records and do not know about this topic, please read my blog titled " Customizing Java Records " first and then come back to this one. Now that you know how to customize Java records, implementing an interface using Java records should be very easy to understand. If you don't know about interfaces in Java, you can read more on my article about interfaces. The recipe for implementing an interface is simply an expansion of what you learned in my previous blog on how to customize a Java record. Following our Rectangle example, let's create an interface with the same two methods we used before. public interface Shape { double area(); double perimeter(); } Now, let's further customize the previous example by doing two things: Add implements Shape at the end of the record declaration (after the record constructor), and Add @Override to the existing methods to ensure these methods com...

Customizing Java Records

If you have not read my article on Java records and do not know about this topic, please read my blog titled " Java Keywords Addendum: The Java Record " first and then come back to this one. What is a customization of a record? A customization of a record is simply the addition of code inside the body of the class. Before proceeding further, let's recap important aspects of a Java Record: Java records are immutable Because of item 1 above, you cannot add new fields unless defined in the record constructor Java records already override: Object#equals(Object) and Object#hashCode() , and then override Object#toString() You could redefine overridden methods as part of your customization if you would like. For example, if you want a fancier implementation of the Object#toString() method, you could do so. Let's look at our first customization example. Using the example from my previous blog, public record Student(...

Object-Oriented Programming Basics: What is in a Class?

EDITORIAL NOTE : This article was published briefly back in 2016 and quickly set back to draft because I wasn't happy with its contents. It is a shame that it was taking me three years to revisit this topic and work on a new and improved version. At least, I'm hoping it will be to the liking you the reader. Keep in mind that the opening paragraph will still read as if I just wrote it for my (former) students at Texas Wesleyan. I started working on lecture on the topic of Object-Oriented (OO) Programming by gathering some material, old and new, when I realized this might be good and simple post for my second attempt at blogging. To be completely honest, in the 8 hours I spent collecting information and preparing material for this week's lecture, I realized I still made some of the mistakes I am about to blog about. I am actually hoping I can write a series of postings regarding Object-Oriented Programming (OOP). But to do so, I must start from the very beginning. ...