Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
7e1c4c7
Implement detach and reattach entity in JPA
saikatcse03 Dec 11, 2025
1b115b3
Merge remote-tracking branch 'origin/master'
saikatcse03 Dec 11, 2025
4368b19
Implement additional tests
saikatcse03 Dec 11, 2025
7178d0a
Merge branch 'eugenp:master' into master
saikatcse03 Dec 11, 2025
faebcfc
Merge branch 'eugenp:master' into master
saikatcse03 Jan 16, 2026
a7ae8df
implemented kafka offset reset
saikatcse03 Jan 18, 2026
edffad7
Merge remote-tracking branch 'origin/master'
saikatcse03 Jan 18, 2026
ca2ed3d
refactored code and test cases
saikatcse03 Jan 19, 2026
83a68a0
refactored code
saikatcse03 Jan 19, 2026
5b15352
refactored code
saikatcse03 Jan 19, 2026
3564b3d
refactored test code
saikatcse03 Jan 19, 2026
f9fae8e
refactored test code
saikatcse03 Jan 20, 2026
77ba154
refactored code
saikatcse03 Jan 20, 2026
7ca07b9
refactored code
saikatcse03 Jan 20, 2026
755d33f
refactored code
saikatcse03 Jan 21, 2026
46bdd7f
refactored code
saikatcse03 Jan 22, 2026
7d025bb
refactored code
saikatcse03 Jan 23, 2026
c7d4a5f
Merge branch 'eugenp:master' into master
saikatcse03 Feb 10, 2026
6a77f5a
API Versioning in Spring boot 4
saikatcse03 Feb 14, 2026
cf6c0e2
API Versioning in Spring boot 4 refactoring
saikatcse03 Feb 15, 2026
2e69dbb
update pom file
saikatcse03 Feb 15, 2026
bbde43f
update pom file
saikatcse03 Feb 15, 2026
b755840
resources file
saikatcse03 Feb 15, 2026
79e967d
refactor code
saikatcse03 Feb 15, 2026
54db6b6
refactor code
saikatcse03 Feb 15, 2026
a59ecab
refactor code
saikatcse03 Feb 15, 2026
e84baaa
refactor code
saikatcse03 Feb 16, 2026
3bea137
refactor tests
saikatcse03 Feb 16, 2026
50f25d9
add more test case
saikatcse03 Feb 16, 2026
f8aad08
update project to parent pom and test case refactor
saikatcse03 Feb 16, 2026
d80e698
update test names
saikatcse03 Feb 23, 2026
cd5899f
update test name and property for surefire
saikatcse03 Feb 23, 2026
fbc2e5d
Merge branch 'eugenp:master' into master
saikatcse03 Mar 17, 2026
70357fc
Merge branch 'eugenp:master' into master
saikatcse03 Mar 23, 2026
e2d958e
Implement virtual thread pinning examples
saikatcse03 Mar 31, 2026
ea2b2f6
remove c related files and rename tests
saikatcse03 Mar 31, 2026
67a3a2b
remove non required dependency
saikatcse03 Mar 31, 2026
9dcaba5
rename variable
saikatcse03 Mar 31, 2026
ebb6430
rename variable
saikatcse03 Mar 31, 2026
8a436e7
include maven-shade-plugin
saikatcse03 Mar 31, 2026
046055d
remove unused property
saikatcse03 Mar 31, 2026
e8f13da
update pom file with unused var removal
saikatcse03 Mar 31, 2026
deb50df
safe unlock handling
saikatcse03 Apr 21, 2026
fbcc2c5
rename variable
saikatcse03 Apr 21, 2026
706bf90
refactor method
saikatcse03 Apr 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions core-java-modules/core-java-concurrency-advanced-7/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,72 @@
<version>${awaitility.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.core.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.core.version}</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source.version}</source>
<target>${maven.compiler.target.version}</target>
<debug>false</debug>
<compilerArgs>
<arg>--enable-preview</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.core.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>--enable-preview</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals><goal>shade</goal></goals>
<configuration>
<finalName>benchmarks</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

<properties>
<awaitility.version>1.7.0</awaitility.version>
<maven.compiler.source.version>21</maven.compiler.source.version>
<maven.compiler.target.version>21</maven.compiler.target.version>
<jmh.core.version>1.37</jmh.core.version>
</properties>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.baeldung.virtualthread.classinit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HeavyClass {

private static final Logger LOGGER = LoggerFactory.getLogger(HeavyClass.class);

static {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}

LOGGER.info("static initialization done");
}

{
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}

LOGGER.info("initialization done");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.baeldung.virtualthread.classloader;

import java.io.IOException;
import java.nio.file.Path;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class CustomClassLoader extends ClassLoader {

private static final Logger LOGGER = LoggerFactory.getLogger(CustomClassLoader.class);
private final Path classDir;

public CustomClassLoader(Path classDir) {
super(ClassLoader.getSystemClassLoader());
this.classDir = classDir;
}

@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
LOGGER.info("Load class for {}", name);

Class<?> clazz = findLoadedClass(name);

if (clazz == null) {
try {
clazz = findClass(name);
} catch (ClassNotFoundException ex) {
clazz = super.loadClass(name, resolve);
}
}

if (resolve) {
resolveClass(clazz);
}

return clazz;
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
LOGGER.info("Finding class for {}", name);

try {
Path file = classDir.resolve(name.replace('.', '/') + ".class");
byte[] bytes = java.nio.file.Files.readAllBytes(file);
Thread.sleep(100);

return defineClass(name, bytes, 0, bytes.length);
} catch (InterruptedException | IOException ex) {
LOGGER.error("Error while finding class file {}", ex.getMessage());
throw new ClassNotFoundException(ex.getMessage(), ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.baeldung.virtualthread.classloader;

public class MyClass {
public MyClass() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.baeldung.virtualthread.foreignfunction;

import static java.lang.foreign.ValueLayout.JAVA_INT;
import static java.lang.foreign.ValueLayout.JAVA_LONG;

import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.Linker;
import java.lang.foreign.SymbolLookup;
import java.lang.invoke.MethodHandle;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ForeignFunctionClass {

private static final Logger LOGGER = LoggerFactory.getLogger(ForeignFunctionClass.class);

public void execute() {
LOGGER.info("Running foreign function sleep...");

Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();
MethodHandle sleep = linker.downcallHandle(stdlib.find("sleep")
.orElseThrow(), FunctionDescriptor.of(JAVA_INT, JAVA_LONG));

try {
sleep.invoke(100);
} catch (Throwable ex) {
System.out.println("Error in native sleep...");
throw new RuntimeException(ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.baeldung.virtualthread.nativemethod;

public class NativeDemo {

static {
System.loadLibrary("native-lib");
}

public native String nativeCall();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.baeldung.virtualthread.synchronize;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

@BenchmarkMode({ Mode.AverageTime, Mode.Throughput })
@OutputTimeUnit(TimeUnit.SECONDS)
@Warmup(iterations = 1, time = 5, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS)
@Fork(value = 2)
@State(Scope.Benchmark)
public class BenchmarkVirtualThread {

private final CartService cartService = new CartService();

@Param({ "100", "1000", "10000" })
private int CONCURRENCY;

@Benchmark
public void benchmark() throws InterruptedException, IOException {
List<Thread> threads = new ArrayList<>();
IntStream.range(0, CONCURRENCY).forEach(i -> threads.add(Thread.startVirtualThread(() -> cartService.update(UUID.randomUUID()
.toString(), 2))));

threads.forEach(th -> {
try {
th.join();
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.baeldung.virtualthread.synchronize;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CartService {

private static final Logger LOGGER = LoggerFactory.getLogger(CartService.class);

private final Map<String, Integer> products;
private final Map<String, Object> locks = new ConcurrentHashMap<>();

public CartService() {
this.products = new HashMap<>();
}

public void update(String productId, int quantity) {
Object lock = locks.computeIfAbsent(productId, k -> new Object());

synchronized (lock) {
simulateAPI();
products.merge(productId, quantity, Integer::sum);
}

LOGGER.info("Updated Cart for {} {}", productId, quantity);
}

public Map<String, Integer> getProducts() {
return Map.copyOf(products);
}

private void simulateAPI() {
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.baeldung.virtualthread.synchronize.fixed;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CartService {

private static final Logger LOGGER = LoggerFactory.getLogger(CartService.class);

private final Map<String, Integer> products;
private final Map<String, ReentrantLock> locks = new ConcurrentHashMap<>();

public CartService() {
this.products = new HashMap<>();
}

public void update(String productId, int quantity) {
Lock lock = locks.computeIfAbsent(productId, k -> new ReentrantLock());

try {
if (lock.tryLock(500, TimeUnit.MILLISECONDS)) {
try {
simulateAPI();
products.merge(productId, quantity, Integer::sum);
} finally {
lock.unlock();
}
LOGGER.info("Updated Cart for {} {}", productId, quantity);
}
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}

private void simulateAPI() {
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}

public Map<String, Integer> getProducts() {
return Map.copyOf(products);
}
}
Loading