Skip to content

Hi,

I’ve created a new github repository for my Java Benchmarks : java-benchmarks

From now all my benchmarks will be pushed to this repository. This is more simple for me to manage and more secure also.

At this time, there is seven benchmarks on the repository :

  1. Closest Pair Search Benchmark : A benchmark to test two closest pair point search algorithms : the naive one and the sweeping plane one. Results.
  2. File Copy Benchmark : A benchmark on the different ways to make file copy in Java. Results.
  3. Iteration Remove Benchmark : A simple benchmark to test if it’s interesting to remove the read elements from a list when we make several iterations over the list.
  4. Reflection Benchmark : A little benchmark to test the performances of reflection versus switch cases and direct invocations.
  5. Short Indexes Loop Benchmark : A benchmark to test which primitive type is the most performing using as iteration index. Results.
  6. Synchronization Benchmark : A benchmark to test the performances of the different synchronization mechanisms available in Java to provide mutual exclusion. Results.
  7. Unmodifiable Benchmark : A benchmark to test the performances of unmodifiable collection versus creating a copy of the list.

I hope you’ll find these sources interesting. If you found errors or improvements, don’t hesitate to comment to tell me what.

I’ve created another benchmark. This time, I’ve benchmarked the different ways of synchronizing a little code using mutual exclusion on this code.

The code to protect will be very simple. It’s a simple counter :

//Init
int counter = 0; 
 
//Critical section
counter++;

The critical section, if not protected with synchronization system, will not function properly due to possible interleavings (read the article on synchronization if you don’t know what is interleaving).

Continue reading ‘Java Synchronization (Mutual Exclusion) Benchmark’ »

We continue with the Java Concurrency thema with the semaphores. Semaphores is also a way to synchronize threads.

Semaphores are a really simple concept, invented by the famous Dutch computer scientist Edsger Dijkstra. Basically a semaphore is a counter (integer) that allows a thread to get into a critical region if the value of the counter is greater than 0. If it’s the case, the counter is decremented by one otherwise, the thread is waiting until it can go. And when the thread go away from the critical region, the counter is incremented by one to allow one more thread to pass the critical region. A semaphore is created with a certain value for its counter. So, you can execute two actions on a semaphore P and V.

By example, if you have a critical that cannot be executed concurrently, you can use a semaphore :

sem mutex = new sem(1)
 
P(mutex)
//Critical region
V(mutex)

So you must always call by yourself the P operation before the critical region and V after it. We call a mutex (mutual exclusion) a semaphore with a value of one. So only one thread can enter the region guarded by the semaphore. This is the most used semaphore. The other use of semaphore is to guard a set of resources like database connections or a data pool.

In Java, a semaphore is created using the java.util.concurrent.Semaphore class. You can create easily :

Semaphore mutex = new Semaphore(1);
Semaphore available = new Semaphore(100);

The P and V operations are represented using the acquire and release methods. The method acquire can be interrupted if the thread is interrupted. There is an ininterruptible version with the method acquireUninterruptibly(). There is also a third version with the tryAcquire method. This method acquire a permit only if there is one permit available, otherwise, this method return false directly. All the waiting methods have also an overloaded version with a timeout. You can also acquire several permits at once using the permits argument to the different versions of acquire methods.

A little example with a mutex using the same example as the previous post on Java concurrency :

public class Example {
    private int value = 0;
 
    private final Semaphore mutex = new Semaphore(1)
 
    public int getNextValue() throws InterruptedException {
        try {
            mutex.acquire();
            return value++;
        } finally {
            mutex.release();
        }
    }
}

For more informations about Semaphore in Java, the best is to consult the Javadoc of the Semaphore class.

To conclude, semaphores are a powerful ways to solve concurrency problems, but this is not adapted to all problems. If you need only mutual exclusion, synchronized blocks are a better solutions. The problems with semaphores is that you can forget to call the release method and that can cause deadlock sometimes difficult to find.

After learning how to create threads and manipulate them, it’s time to go to most important things : synchronization.

Synchronization is a way to make some code thread safe. A code that can be accessed by multiple threads must be made thread safe. Thread Safe describe some code that can be called from multiple threads without corrupting the state of the object or simply doing the thing the code must do in right order.

For example, we can take this little class :

public class Example {
    private int value = 0;    
 
    public int getNextValue(){
        return value++;
    }
}

It’s really simple and works well with one thread, but absolutely not with multiple threads. An incrementation like this is not a simple action, but three actions :

  • Read the current value of “value”
  • Add one to the current value
  • Write that new value to “value”

Normally, if you have two threads invoking the getNextValue(), you can think that the first will get 1 and the next will get 2, but it is possible that the two threads get the value 1. Imagine this situation :

Thread 1 : read the value, get 0, add 1, so value = 1
Thread 2 : read the value, get 0, add 1, so value = 1
Thread 1 : write 1 to the field value and return 1
Thread 2 : write 1 to the field value and return 1

These situations come from what we call interleaving. Interleaving describe the possible situations of several threads executing some statements. Only for three operations and two threads, there is a lot of possible interleavings.

So we must made the operations atomic to works with multiple threads. In Java, the first way to make that is to use a lock. All Java objects contains an intrinsic locks, we’ll use that lock to make methods or statement atomic. When a thread has a lock, no other thread can acquire it and must wait for the first thread to release the lock. To acquire the lock, you have to use the synchronized keyword to automatically acquire and release a lock for a code. You can add the synchronized keyword to a method to acquire the lock before invoking the method and release it after the method execution. You can refactor the getNextValue() method using the synchronized keyword :

public class Example {
    private int value = 0;    
 
    public synchronized int getNextValue(){
        return value++;
    }
}

With that, you have the guarantee that only thread can execute the method at the same time. The used lock is the intrinsic lock of the instance. If the method is static, the used lock is the Class object of Example. If you have two methods with the synchronized keyword, only one method of the two will be executed at the same time because the same lock is used for the two methods. You can also write it using a synchronized block :

public class Example {
    private int value = 0;
 
    public int getNextValue() {
        synchronized (this) {
            return value++;
        }
    }
}

This is exactly the same as using the synchronized keyword on the method signature. Using synchronized blocks, you can choose the lock to block on. By example, if you don’t want to use the intrinsic lock of the current object but an other object, you can use an other object just as a lock :

public class Example {
    private int value = 0;
 
    private final Object lock = new Object();
 
    public int getNextValue() {
        synchronized (lock) {
            return value++;
        }
    }
}

The result is the same but has one difference, the lock is internal to the object so no other code can use the lock. With complex classes, it not rare to use several locks to provide thread safety on the class.

There is an other issue with multiple threads : the visibility of the variables. This seems when a change made by a thread is visible by an other thread. For performance improvements, the Java compiler and virtual machines can made some improvements using registers and cache. By default, you have no guarantee that a change made by a thread is visible to an other thread. To make a change visible to an other thread, you must use synchronized blocks to ensure visibility of the change. You must use synchronized blocks for the read and for the write of the shared values. You must make that for every read/write of a value shared between multiple threads.

You can also use the volatile keyword on the field to ensure the visibility of read/write between multiple threads. The volatile keyword ensure only visibility, not atomicity. The synchronized blocks ensure visibility and atomicity. So you can use the volatile keyword on fields that doesn’t need atomicity (if you make only read and write to the field without depending on the current value of the field by example).

You can also note that this simple example can be solved using AtomicInteger, but that will be covered later in an other part of the posts.

Pay attention that trying to solve thread safety on a problem can add new issues of deadlock. By example, if thread A owns the lock 1 and are waiting for the lock 2 and if lock 2 is acquired by thread B who waits on lock 1, there is a deadlock. Your program is dead. So you have to pay great attention to the locks.

There is several rules that we must keep in mind when using locks :

  1. Every mutable fields shared between multiple threads must be guarded with a lock or made volatile, if you only need visibility
  2. Synchronize only the operations that must synchronized, this improve the performances. But don’t synchronize too few operations. Try to keep the lock only for short operations.
  3. Always know which locks are acquired and when there are acquired and by which thread
  4. An immutable object is always thread safe

Here we are, I hope that this post helps you to understand thread safety and how to achieve it using intrinsic locks. In the next posts, we’ll see another synchronization methods.

I’ve made another updates to my file copy benchmark.

First of all, I used my little utility class to automatically create the graphs. The graph are a little less clean, but I spare a lot of time not creating them myself.

Then, I’ve also made some corrections on the code :

  • I”ve used a buffer size of 8192 instead of 4096
  • I’ve made some corrections using the channels because the old code can forgot to write some portions of the file
  • I used allocateDirect() instead of allocate() for the ByteBuffer.

And I’ve added a new method using Java 7 : Path.copyTo(Path path).

So the new results are all based on a Java 7 Virtual Machine.

You’ll find all the new informations and result, on the original post : File Copy in Java – Benchmark

I hope this new informations will interest you.

From the build 105, the compiler and runtime of Java 7 Releases have support for the new form of try : try-with-resources, also called ARM (Automatic Resource Management) blocks.

This new statement make working with streams and all kind of closeable resources easier. By example, in Java, you can have this kind of code :

private static void customBufferStreamCopy(File source, File target) {
    InputStream fis = null;
    OutputStream fos = null;
    try {
        fis = new FileInputStream(source);
        fos = new FileOutputStream(target);
 
        byte[] buf = new byte[8192];
 
        int i;
        while ((i = fis.read(buf)) != -1) {
            fos.write(buf, 0, i);
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    } finally {
        close(fis);
        close(fos);
    }
}
 
private static void close(Closeable closable) {
    if (closable != null) {
        try {
            closable.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

A little bit heavy, isn’t it ? This is only an example, here the management of exceptions is not good.

So let’s use try-with-resources statement to simplify this code, who becomes :

private static void customBufferStreamCopy(File source, File target) {
    try (InputStream fis = new FileInputStream(source);
        OutputStream fos = new FileOutputStream(target)){
 
        byte[] buf = new byte[8192];
 
        int i;
        while ((i = fis.read(buf)) != -1) {
            fos.write(buf, 0, i);
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

A lot cleaner, no ? With that code, the resources are automatically closed after the try. In the try resources list, you can declare several resources, but all these resources must implement the java.lang.AutoCloseable interface.

If you want more informations, about this new statement read try-with-resources specifications.

Hi,

I used my holidays to concentrate myself on the reading of my last book : Java Concurrency in Practice of Brian Goetz (with Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes and Doug Lea).

This book is, in my point of view, the reference for the development of concurrency programs in Java.

Reading this book, you will learn that concurrency is everywhere when programming in Java (all the examples are in Java, but the theory  is valid for almost all programming languages). You will also learn why the GUI Frameworks are single-threaded. You will also understand that a lot of Java programs aren’t correct because of the lack of thread safety.

The first chapter, the introduction, explains what’s are the threads and why we use parallel processing. It contains also the first interleaving example (really simple) and how to solve it. In the third chapter, the author explains what is Thread Safety and how to achieve it using locks (intrinsic locks with synchronized). In the next chapter, you learn how to share objects between several threads. This include the notions of visibility, immutability, thread confinement and safe publication. With the fourth chapter, you learn how to design a thread safe class, delegate the thread safety to an other class and learn why it’s really important to document the synchronization policies. In the last chapter of this first part, we see how to build blocks of statements. We use concurrent collections, blocking queues, synchronizers, blocking and interruptible methods.

The second part is about structuring concurrent applications. It contains information about the executor framework, finding parallelism, the cancellation and the shutdown of tasks, the thread pools and the GUI applications.

The third part is about liveness hazards, performance and scalability and also about testing concurrent programs.

The last part describe advanced topics. It contains explicit locks using ReentrantLock. It explains also how to build custom synchronizers. A chapter is about building concurrent programs using non-blocking algorithms. This algorithms are better performing but a lot more difficult to build. And the last chapter is about the Java Memory Model. This chapter is very technical but really interesting if you are interested to understand deeply the Java language.

To conclude, this book is a reference for every person who want to write concurrent applications.

Post Scriptum : This is the hundredth post of this blog. I’m proud to see that there is a lot of regular readers and I hope that this blog will live long.

Monday, I will go on holidays for one week. I’ll not have internet except on my smartphone, so I’ll not post on this blog during one week.

I will just approve comments and perhaps answer to comments if this is necessary, but this is all.

So, to next week.

Hi,

I’ve the pleasure to inform you that I’ve created a new website in English for JTheque : http://www.jtheque.com

The old websites of JTheque (a French website and a French forge) were completely out of date and were too complicated too manage. This time I created an english, really simple, website to add the more useful informations about my JTheque projects. I always wanted to have a real website for JTheque. Before that, I had the Maven auto generated websites, but this is not a real website and it’s not really good-looking. I used Google Sites to create this website.

At this time, I’ve included three projects in the website : JTheque Core, JTheque Utils and JTheque XML Utils. There is not a lot of informations for the moment,  but from this time I’ll include all the future informations in this new website and I will of course inform you via this blog of all the informations about my projects.

I hope that this website will interest you and that it will help to promote a little my JTheque Project.

If you found any error on the website, don’t hesitate to contact me, via comment or email or whatever you want. If you need more informations on one or more project, don’t hesitate to request them and I will include them in the website as soon as possible.

A little tip that can be useful and save a lot of time : Do not use relative path with LogBack.

I wondered why this little LogBack configuration didn’t work :

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <contextName>JTheque</contextName>
 
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/jtheque.log</file>
 
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <FileNamePattern>logs/jtheque.%i.log.zip</FileNamePattern>
            <MinIndex>1</MinIndex>
            <MaxIndex>5</MaxIndex>
        </rollingPolicy>
 
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>5MB</MaxFileSize>
        </triggeringPolicy>
 
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
        </layout>
    </appender>
 
    <root level="DEBUG">
        <appender-ref ref="FILE"/>
    </root>
</configuration>

No file were written. I searched during a long time and after that tested with an absolute path and it worked really well. But absolute path is not very good. But, you can use system properties in the configuration, so I used user.dir to make the think works :

        ...
        <file>${user.dir}/logs/jtheque.log</file>
 
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <FileNamePattern>${user.dir}/logs/jtheque.%i.log.zip</FileNamePattern>
            <MinIndex>1</MinIndex>
            <MaxIndex>5</MaxIndex>
        </rollingPolicy>
        ...

And this time, it works well !

Hope this will be useful to somebody.