Java Concurrency
Concurrency Nədir?
Java Concurrency eyni zamanda bir neçə thread-in işləməsini təmin edir. Bu performansı artırır və sistem resurslarından effektiv istifadə edir.
Thread Həyat Dövrü
- NEW - Thread yaradılıb, start() çağırılmayıb
- RUNNABLE - Thread işləməyə hazır və ya işləyir
- BLOCKED - Monitor lock gözləyir
- WAITING - Başqa thread-in notification-unu gözləyir
- TIMED_WAITING - Müəyyən müddət gözləyir
- TERMINATED - İşini bitirıb
Thread Yaratmaq
Thread Class-ını Extend Etmək
class MyThread extends Thread {
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(name + " - " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
}
}
}
// İstifadə
MyThread t1 = new MyThread("Thread-1");
MyThread t2 = new MyThread("Thread-2");
t1.start();
t2.start();
Runnable Interface-ini İmplement Etmək
class MyTask implements Runnable {
private String name;
public MyTask(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(name + " - " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
}
}
}
// İstifadə
Thread t1 = new Thread(new MyTask("Task-1"));
Thread t2 = new Thread(new MyTask("Task-2"));
t1.start();
t2.start();
Lambda ilə
Thread t = new Thread(() -> {
for (int i = 1; i <= 3; i++) {
System.out.println("Lambda Thread - " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
}
});
t.start();
Synchronization
synchronized Keyword
class Counter {
private int count = 0;
// Synchronized method
public synchronized void increment() {
count++;
}
// Synchronized block
public void decrement() {
synchronized(this) {
count--;
}
}
public synchronized int getCount() {
return count;
}
}
Static Synchronization
class StaticCounter {
private static int count = 0;
public static synchronized void increment() {
count++;
}
public static synchronized int getCount() {
return count;
}
}
Wait və Notify
class WaitNotifyExample {
private boolean ready = false;
public synchronized void producer() throws InterruptedException {
Thread.sleep(2000);
ready = true;
System.out.println("Producer: Data hazır");
notify(); // Waiting thread-i oyat
}
public synchronized void consumer() throws InterruptedException {
while (!ready) {
wait(); // Ready olana qədər gözlə
}
System.out.println("Consumer: Data istifadə edildi");
}
}
Executor Framework
ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(3);
// Task-ları göndər
for (int i = 1; i <= 5; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("Task " + taskId + " işləyir");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
return;
}
System.out.println("Task " + taskId + " bitdi");
});
}
executor.shutdown();
Müxtəlif Executor Tipləri
// Fixed thread pool
ExecutorService fixed = Executors.newFixedThreadPool(4);
// Single thread
ExecutorService single = Executors.newSingleThreadExecutor();
// Cached thread pool
ExecutorService cached = Executors.newCachedThreadPool();
// Scheduled executor
ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(2);
scheduled.scheduleAtFixedRate(() -> {
System.out.println("Periodic task");
}, 0, 5, TimeUnit.SECONDS);
CompletableFuture
// Async task
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
return "Error";
}
return "Hello World";
});
// Result al
String result = future.get(); // Blocking
System.out.println(result);
// Non-blocking
future.thenAccept(System.out::println);
CompletableFuture Chaining
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> "Hello")
.thenApply(s -> s + " World")
.thenApply(String::toUpperCase);
future.thenAccept(System.out::println); // HELLO WORLD
Thread-Safe Collections
// Vector (thread-safe ArrayList)
List<String> vector = new Vector<>();
// Hashtable (thread-safe HashMap)
Map<String, Integer> hashtable = new Hashtable<>();
// Collections.synchronizedXXX
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());
// ConcurrentHashMap
Map<String, Integer> concurrentMap = new ConcurrentHashMap<>();
// BlockingQueue
BlockingQueue<String> queue = new LinkedBlockingQueue<>();
queue.put("item"); // Blocking put
String item = queue.take(); // Blocking take
Volatile Keyword
class VolatileExample {
private volatile boolean running = true;
public void start() {
new Thread(() -> {
int count = 0;
while (running) {
count++;
}
System.out.println("Thread stopped. Count: " + count);
}).start();
}
public void stop() {
running = false; // Bu dəyişiklik digər thread tərəfindən görünəcək
}
}
Atomic Classes
AtomicInteger atomicInt = new AtomicInteger(0);
// Thread-safe increment
atomicInt.incrementAndGet();
atomicInt.decrementAndGet();
// Compare and set
int expected = 5;
int newValue = 10;
boolean success = atomicInt.compareAndSet(expected, newValue);
// Digər atomic siniflər
AtomicLong atomicLong = new AtomicLong(0);
AtomicBoolean atomicBoolean = new AtomicBoolean(false);
AtomicReference<String> atomicRef = new AtomicReference<>("initial");
Best Practices
-
Runnable > Thread extend:
// Yaxşı
Thread t = new Thread(() -> doWork());
// Pisdir (single inheritance limitation)
class MyThread extends Thread { } -
ExecutorService istifadə edin:
// Thread pool istifadə edin
ExecutorService executor = Executors.newFixedThreadPool(4); -
Thread-safe collections:
// ConcurrentHashMap > synchronized HashMap
Map<String, String> map = new ConcurrentHashMap<>(); -
Volatile shared variables üçün:
private volatile boolean flag = false; -
Executor-ları bağlayın:
executor.shutdown();
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
Common Problems
Deadlock
// İki thread qarşılıqlı lock gözləyir
Object lock1 = new Object();
Object lock2 = new Object();
// Thread 1
synchronized(lock1) {
synchronized(lock2) { /* work */ }
}
// Thread 2
synchronized(lock2) {
synchronized(lock1) { /* work */ } // Deadlock!
}
Race Condition
// Thread-safe deyil
class UnsafeCounter {
private int count = 0;
public void increment() {
count++; // Read-modify-write - race condition!
}
}
// Thread-safe
class SafeCounter {
private int count = 0;
public synchronized void increment() {
count++;
}
}