Əsas məzmuna keçin

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ü

  1. NEW - Thread yaradılıb, start() çağırılmayıb
  2. RUNNABLE - Thread işləməyə hazır və ya işləyir
  3. BLOCKED - Monitor lock gözləyir
  4. WAITING - Başqa thread-in notification-unu gözləyir
  5. TIMED_WAITING - Müəyyən müddət gözləyir
  6. 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

  1. Runnable > Thread extend:

    // Yaxşı
    Thread t = new Thread(() -> doWork());

    // Pisdir (single inheritance limitation)
    class MyThread extends Thread { }
  2. ExecutorService istifadə edin:

    // Thread pool istifadə edin
    ExecutorService executor = Executors.newFixedThreadPool(4);
  3. Thread-safe collections:

    // ConcurrentHashMap > synchronized HashMap
    Map<String, String> map = new ConcurrentHashMap<>();
  4. Volatile shared variables üçün:

    private volatile boolean flag = false;
  5. 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++;
}
}