Merge pull request #15124 from michael-pratt/BAEL-7074

BAEL-7074: Static variable synchronization techniques
This commit is contained in:
davidmartinezbarua 2023-11-12 18:15:09 -03:00 committed by GitHub
commit 5e681a24dd
7 changed files with 281 additions and 0 deletions

View File

@ -0,0 +1,30 @@
package com.baeldung.concurrent.synchronizestatic.atomicinteger;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Synchronizing static variable with AtomicInteger.
*/
public class Employee {
private static final AtomicInteger count = new AtomicInteger(0);
int id;
String name;
String title;
public Employee(int id, String name, String title) {
incrementCount();
this.id = id;
this.name = name;
this.title = title;
}
private static void incrementCount() {
count.incrementAndGet();
}
public static int getCount() {
return count.get();
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.concurrent.synchronizestatic.none;
/**
* No synchronization.
*/
public class Employee {
static int count;
int id;
String name;
String title;
public Employee(int id, String name, String title) {
incrementCount();
this.id = id;
this.name = name;
this.title = title;
}
private static void incrementCount() {
System.out.println("Count = " + ++count);
}
public static Integer getCount() {
return count;
}
}

View File

@ -0,0 +1,43 @@
package com.baeldung.concurrent.synchronizestatic.reentrantlock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Synchronizing static variable with a Reenatrant Lock.
*/
public class Employee {
private static final ReentrantLock lock = new ReentrantLock();
static int count;
int id;
String name;
String title;
public Employee(int id, String name, String title) {
incrementCount();
this.id = id;
this.name = name;
this.title = title;
}
private static void incrementCount() {
lock.lock();
try {
System.out.println("Count = " + ++count);
}
finally {
lock.unlock();
}
}
public static int getCount() {
lock.lock();
try {
return count;
}
finally {
lock.unlock();
}
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.concurrent.synchronizestatic.synchronizedblock;
/**
* Synchronizing static variable with a synchronized block.
*/
public class Employee {
private static final Object lock = new Object();
static int count;
int id;
String name;
String title;
public Employee(int id, String name, String title) {
incrementCount();
this.id = id;
this.name = name;
this.title = title;
}
private static void incrementCount() {
synchronized(lock) {
System.out.println("Count = " + ++count);
}
}
public static int getCount() {
synchronized(lock) {
return count;
}
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.concurrent.synchronizestatic.synchronizedclass;
/**
* Synchronizing static variable with a synchronized block.
*/
public class Employee
{
static int count;
int id;
String name;
String title;
public Employee(int id, String name, String title) {
incrementCount();
this.id = id;
this.name = name;
this.title = title;
}
private static void incrementCount() {
synchronized(Employee.class) {
System.out.println("Count = " + ++count);
}
}
public static int getCount() {
synchronized(Employee.class) {
return count;
}
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.concurrent.synchronizestatic.synchronizedmethod;
/**
* Synchronizing static variable with a synchronized method.
*/
public class Employee {
static int count;
int id;
String name;
String title;
public Employee(int id, String name, String title)
{
incrementCount();
this.id = id;
this.name = name;
this.title = title;
}
private static synchronized void incrementCount() {
System.out.println("Count = " + ++count);
}
public static synchronized int getCount() {
return count;
}
}

View File

@ -0,0 +1,90 @@
package com.baeldung.concurrent.synchronizestatic;
import org.junit.Test;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* The tests in this class show the output of creating multiple
* types of Employee classes in the <code>synchronizedstatic</code>
* package. When not synchronized the out will not be sequential;
* when it is synchronized the output will be in sequential.
*/
public class SychronizeStaticDataUnitTest {
private final Executor pool = Executors.newFixedThreadPool(4);
private final int numberToTest = 100;
@Test
public void whenNotSynchronized_thenDataOutOfOrder() {
System.out.println("No synchronization");
for(int i = 0; i < numberToTest; i++) {
int finalI = i;
pool.execute(() -> {
new com.baeldung.concurrent.synchronizestatic.none.Employee(finalI, "John", "Smith");
});
}
}
@Test
public void whenSynchronizedMethod_thenDataInOrder() {
System.out.println("Synchronization with synchronized method");
for(int i = 0; i < numberToTest; i++) {
int finalI = i;
pool.execute(() -> {
new com.baeldung.concurrent.synchronizestatic.synchronizedmethod.Employee(finalI, "John", "Smith");
});
}
}
@Test
public void whenSynchronizedClass_thenDataInOrder() {
System.out.println("Synchronization with synchronized block on class");
for(int i = 0; i < numberToTest; i++) {
int finalI = i;
pool.execute(() -> {
new com.baeldung.concurrent.synchronizestatic.synchronizedclass.Employee(finalI, "John", "Smith");
});
}
}
@Test
public void whenSynchronizedBlock_thenDataInOrder() {
System.out.println("Synchronization with synchronized block on a private object");
for(int i = 0; i < numberToTest; i++) {
int finalI = i;
pool.execute(() -> {
new com.baeldung.concurrent.synchronizestatic.synchronizedblock.Employee(finalI, "John", "Smith");
});
}
}
@Test
public void whenAtomicInteger_thenDataInOrder() {
// Not straight forward to test this because we cannot log/print
// and increment values in a synchronized fashion like other
// tests
}
@Test
public void whenReentrantLock_thenDataInOrder() {
System.out.println("Synchronization with ReentrantLock");
for(int i = 0; i < numberToTest; i++) {
int finalI = i;
pool.execute(() -> {
new com.baeldung.concurrent.synchronizestatic.reentrantlock.Employee(finalI, "John", "Smith");
});
}
}
}