Skip to content

Yet another programming solutions log

Sample bits from programming for the future generations.

Technologies Technologies
  • Algorithms and Data Structures
  • Java Tutorials
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Spock Framework Tutorial
  • Spring Framework
  • Bash Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Developer’s Tools
  • Productivity
  • About
Expand Search Form

Java synchronize static

farenda 2015-11-16 0

Problem:

How to synchronize concurrent modifications of static data in Java? In this post we’re going to solution to this common, multi-threaded, problem. Read on!

In previous posts (Java synchronized method and Java synchronized object) we’ve shown how to safely modify object’s state in multi-threaded environment. Here the problem is a bit different, because data is static (class field instead of an instance field) as in the following example.

In the following code, the number is static and we have a static method that is used to modify it by a few threads concurrently:

package com.farenda.java.lang;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ThreadSynchronizeOnClass {

    private static int number;

    public static boolean dec() {
        if (number > 0) {
            Thread.yield();
            --number;
            return true;
        }
        return false;
    }

    private static class Worker implements Runnable {

        private static int nth = 0;

        private final int id = ++nth;

        @Override
        public void run() {
            System.out.println("Starting worker: " + id);
            while (dec()) {
                System.out.printf("Decreased to %2d by worker: %2d%n",
                        ThreadSynchronizeOnClass.number, id);
            }
        }
    }

    public static void main(String[] args) {
        ThreadSynchronizeOnClass.number = 10;
        ExecutorService executor = Executors.newCachedThreadPool();
        for (int i = 1; i <= 10; ++i) {
            executor.execute(new Worker());
        }
        executor.shutdown();

        try {
            executor.awaitTermination(2, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            //ignore
        }

        System.out.println("Number actually is: " + ThreadSynchronizeOnClass.number);
    }
}

When we run the above code, we can quickly notice that the result is not what we expected (sorted for readability):

Starting worker: 1
Starting worker: 2
Starting worker: 3
Starting worker: 4
Starting worker: 5
Starting worker: 6
Starting worker: 7
Starting worker: 8
Starting worker: 9
Starting worker: 10
Decreased to  9 by worker:  1
Decreased to  8 by worker:  1
Decreased to  7 by worker:  1
Decreased to  6 by worker: 10
Decreased to  5 by worker:  7
Decreased to  4 by worker:  6
Decreased to  3 by worker:  8
Decreased to  2 by worker:  9
Decreased to  1 by worker:  6
Decreased to  0 by worker:  9
Decreased to -1 by worker:  8
Decreased to -2 by worker:  7
Decreased to -3 by worker:  6
Number actually is: -3

Solution:

The problem can be solve is a similar way to the solutions that we’ve shown in posts Java synchronized method and Java synchronized object, namely:

  • synchronize access on static method level,
  • synchronize access using lock object.

Adding synchronized to the static method works, but has a bit different meaning as in the previous post:

public static synchronized boolean dec() {
    if (number > 0) {
        Thread.yield();
        --number;
        return true;
    }
    return false;
}

In case of static methods, the synchronized keyword operates on class lock instead of object’s lock. Remember that every class has corresponding instance of java.lang.Class object, which defines this class. So does our ThreadSynchronizeOnClass class. Now Threads that want to access dec method will try to lock on class of ThreadSynchronizeOnClass.

Synchronization using lock object works in the same way as described in Java synchronized object, but the lock object is a static field:

private static final Object lock = new Object();

public static boolean dec() {
    synchronized(lock) {
        if (number > 0) {
            Thread.yield();
            --number;
            return true;
        }
        return false;
    }
}

Running the above example with any of those synchronizations gives correct result:

Starting worker: 1
Starting worker: 2
Starting worker: 3
Starting worker: 4
Starting worker: 5
Starting worker: 6
Starting worker: 7
Starting worker: 8
Starting worker: 9
Starting worker: 10
Decreased to  9 by worker:  2
Decreased to  8 by worker:  2
Decreased to  7 by worker:  3
Decreased to  6 by worker:  3
Decreased to  5 by worker:  3
Decreased to  4 by worker:  1
Decreased to  3 by worker:  3
Decreased to  2 by worker:  2
Decreased to  1 by worker: 10
Decreased to  0 by worker: 10
Number actually is: 0

Presto! :-)

Share with the World!
Categories Java Tags java, java-concurrency
Previous: Java synchronized object
Next: Java ReentrantLock

Recent Posts

  • Java 8 Date Time concepts
  • Maven dependency to local JAR
  • Caesar cipher in Java
  • Java casting trick
  • Java 8 flatMap practical example
  • Linked List – remove element
  • Linked List – insert element at position
  • Linked List add element at the end
  • Create Java Streams
  • Floyd Cycle detection in Java

Pages

  • About Farenda
  • Algorithms and Data Structures
  • Bash Tutorial
  • Bean Validation Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Java 8 Streams and Lambda Expressions Tutorial
  • Java Basics Tutorial
  • Java Collections Tutorial
  • Java Concurrency Tutorial
  • Java IO Tutorial
  • Java Tutorials
  • Java Util Tutorial
  • Java XML Tutorial
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Software Developer’s Tools
  • Spock Framework Tutorial
  • Spring Framework

Tags

algorithms bash bean-validation books clojure design-patterns embedmongo exercises git gof gradle groovy hateoas hsqldb i18n java java-basics java-collections java-concurrency java-io java-lang java-time java-util java-xml java8 java8-files junit linux lists log4j logging maven mongodb performance quartz refactoring regex rest slf4j solid spring spring-boot spring-core sql unit-tests

Yet another programming solutions log © 2021

sponsored