Java Thread Sınıfı
Tags: java, thread, synchronized
Published: 2022-01-19 09:48:50

Thread yapısı, aynı anda ve birbirini beklemeden birden çok işin gerçekleşebildiği yapıdır.

Thread oluştururken, java'da <u>thread sınıfı extend edilebilir</u> ya da <u>runnable implementasyonu</u> tercih edilebilir.

Java'da sadece bir sınıf extend edilebildiği ve daha fazla esneklik sağlamak için <u>runnable implementasyonu</u> daha avantajlıdır.

**Önemli tanımlar**
**Runnable:** Thread tanımlarının ne yapması gerektiğini açıklayan bir arayüzdür. 
**Run:** Ana thread bekleme yaparak, diğer thread'ler çalışır. 
**Start:** Ana thread bekleme yapmadan, diğer threadler ile birlikte çalışır.
**Join:** Mevcut thread işini bitirmeden, diğer thread işine başlayamaz.,
**Synchronized:** Method'a ulaşmak isteyen threadler method'a sıra ile girerler ve bir thread method'u bitirmeden diğer thread başlayamaz. (Kilitleme mekanizması vardır. Özetle, thread'ler birbirlerinin üstüne basmazlar)

**Örnek Uygulama 1**


```java
package com.app.thread;
import java.util.List;

public class ThreadExample extends Thread implements Runnable{
    private List<Integer> v;
    public Integer sum = 0;

    public ThreadExample(List<Integer> p) {
        this.v = p;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " started..");
        // Kilit mekanızması ihtiyaç dahilinde kullanılmalıdır.
        // Bu örnekte ihtiyaç yoktur.
        //synchronized(this) {
         for (Integer i : v) {
           sum += i;
         }
         System.out.println(Thread.currentThread().getName() + " => The sum: " + sum);
        //}
    }
    public Integer getSum() {
        return sum;
    }
}
```

```java
package com.app.thread;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main{
    public static void main(String[] args) {
        List<Integer> v = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8));
        List<ThreadExample> allThreads = new ArrayList<>();

        int threadCount = 3; int totalSum = 0; int startIndex = 0;
        // Her bir thread ne kadarlık iş yapacak.
        int perCountOfThread = v.size() / threadCount + ((v.size() % threadCount == 0) ? 0 : 1);

        // Belirlenen dinamik thread sayısı kadar thread başlatılıyor.
        for(int i=1; i<=threadCount; i++) {
            int lastIndex = Math.min((startIndex + perCountOfThread), v.size());
            ThreadExample thread = new ThreadExample(v.subList(startIndex, lastIndex));
            thread.start();
            // Başlatılan tüm threadleri bir listeye alıyoruz.
            allThreads.add(thread);
            startIndex = startIndex+perCountOfThread;
        }

        // İşini bitiren threadleri bir listeye alınıyor.
        // Sonuçlar ana thread tarafından toplanıyor.
        List<String> completedThread = new ArrayList<>();
        while (completedThread.size() != threadCount) {
            for (ThreadExample tempThread : allThreads) {
                if (!tempThread.isAlive() && !completedThread.contains(tempThread.getName())) {
                    totalSum += tempThread.getSum();
                    completedThread.add(tempThread.getName());
                }
            }
        }

        System.out.println(Thread.currentThread().getName() + " => The sum: " + totalSum);
    }
}

```

**Program Çıktısı**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lgv4ymwdp0tu7ghedele.png)

**Not:** <u>Thread.join()</u>, iş parçacığının tamamen bitmesini beklerken, iki iş parçacığının aynı anda aynı kod parçasını yürütmesini önlemek için <u>synchronized</u> bir blok kullanılabilir.

**Örnek Uygulama 2**
```java
package com.app.thread;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main{
    public static void main(String[] args){
        List<Integer> v = new ArrayList<>(Arrays.asList(1, 2, 3,4));

        ThreadExample thread1 = new ThreadExample(v);
        ThreadExample thread2 = new ThreadExample(v);
        
        try {
            thread1.start();
            thread1.join(); // thread2 çalışabilmek için bekleyecektir.
            thread2.start();
            thread2.join(); // main thread çalışabilmek için bekleyecektir.
           // start yerine run kullanılırsa, 
           // main thread 2 numaralı thread'i beklemeyecek 
           // böylece thread2.join() satırına ihtiyaç duyulmayacaktır. 
        }catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }

        Integer totalSum = thread1.getSum() + thread2.getSum();
        System.out.println(Thread.currentThread().getName() + " => The sum: " + totalSum);
    }
}
```
**Program Çıktısı**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9domc38kptxuoruob02o.png)