2 Commits
Author SHA1 Message Date
Mobina 6cc7bfba29 adding bonus part 2026-07-17 23:06:29 +03:30
Mobina 86882ca197 Completion of the specified parts 2026-07-17 23:02:03 +03:30
7 changed files with 156 additions and 4 deletions
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="HW-09-Advanced-Multithreading" />
</profile>
</annotationProcessing>
</component>
</project>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>
+20
View File
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://mirror-maven.runflare.com/maven2" />
</remote-repository>
</component>
</project>
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="25" project-jdk-type="JavaSDK" />
</project>
Generated
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+43
View File
@@ -0,0 +1,43 @@
1 -
زمانی که میخواهیم عملیات های ساده روی یک متغیر داخل thread انجام دهیم یک شیئ atomic variable داخل آن نخ میسازیم و برای انجام عملیات از توابع داخل آن کلاس استفاده میکنیم.
این متغیر ها این خصوصیت را دارند که هنگامی که عملیاتی روی آن درحال اجراست thread دیگری اجرا نمیشود در نتیجه در محاسبه مقدار خطا ایجاد نمیشود.
2 -
AtomicInteger, AtomicLong, AtomicBoolean, AtomicReference<T>
3 - Compare locks with atomic variables.
متغیر های اتمی برای عملیات های ساده استفاده میشود اما قفل برای عملیات های پیچیده تر استفاده میشود و برای چند متغیر استفاده میشود.
🎯Bonus Task:
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicDemo {
private static int normalCounter = 0;
private static AtomicInteger atomicCounter = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < 10000; j++) {
normalCounter++;
atomicCounter.incrementAndGet();
}
});
}
for (Thread t : threads) {
t.start();
}
for (Thread t : threads) {
t.join();
}
System.out.println( normalCounter);
System.out.println( atomicCounter.get());
}
}
@@ -1,9 +1,12 @@
package dev.banking.model; package dev.banking.model;
import java.util.concurrent.locks.ReentrantLock;
public class BankAccount { public class BankAccount {
private final int accountId; private final int accountId;
private long balance; private long balance;
private final ReentrantLock lock = new ReentrantLock();
/* /*
* Students may introduce additional fields * Students may introduce additional fields
@@ -32,7 +35,16 @@ public class BankAccount {
* - Should not block unnecessarily if using read/write locks * - Should not block unnecessarily if using read/write locks
*/ */
public long getBalance() { public long getBalance() {
throw new UnsupportedOperationException("TODO: implement thread-safe balance read");
lock.lock();
try{
return balance;
}finally {
lock.unlock();
}
} }
/* /*
@@ -43,7 +55,14 @@ public class BankAccount {
* - Must not lose updates under concurrency * - Must not lose updates under concurrency
*/ */
public void deposit(long amount) { public void deposit(long amount) {
throw new UnsupportedOperationException("TODO: implement thread-safe deposit");
lock.lock();
try{
balance+=amount;
}finally {
lock.unlock();
}
} }
/* /*
@@ -56,7 +75,12 @@ public class BankAccount {
* to extend the system (optional) * to extend the system (optional)
*/ */
public void withdraw(long amount) { public void withdraw(long amount) {
throw new UnsupportedOperationException("TODO: implement thread-safe withdraw"); lock.lock();
try{
balance-=amount;
}finally {
lock.unlock();
}
} }
/* /*
@@ -73,6 +97,33 @@ public class BankAccount {
* - Or tryLock with retry strategy * - Or tryLock with retry strategy
*/ */
public void transfer(BankAccount target, long amount) { public void transfer(BankAccount target, long amount) {
throw new UnsupportedOperationException("TODO: implement atomic deadlock-free transfer"); BankAccount first;
BankAccount second;
if (this == target) {
return;
}
if (this.getAccountId() < target.getAccountId()) {
first = this;
second = target;
} else {
first = target;
second = this;
}
first.lock.lock();
try {
second.lock.lock();
try {
this.balance -= amount;
target.balance += amount;
} finally {
second.lock.unlock();
}
} finally {
first.lock.unlock();
}
} }
} }