2. Thread (Iş parçacığı)
Eş zamanlı olarak çalıştırılacak birden fazla task(işlem) aynı anda yürütmek için
kullanılır.
Threadler iş parçacıkları olup, çoklu görevlerde senkronizasyonu sağlamak için
kullanılır. Her threadin farklı bir görevi vardır. Eğer bu threadler aynı anda aynı
bölgeye girerse hatalar (deadlock) meydana gelebilir.
Örneğin:Bilgisayar da aynı anda müzik dinlemek,oyun oynamak ,internet girmek vs.
new Thread()
Oluştur(Create)
Çalışıyor(Running)
start()
stop() Wait()
Sleep()
wait()
notify()
notifyAll()sleep()
stop()
3. Runnable Arabirimini Uygulamak
Bir kanal kanal oluşturmanın en basit yolu Runnable arabirimini
uygulayan bir sınıf oluşturmaktır.
Runnable çalıştırılabilir bir kod birimini özetler.Runnable uygulamak
için ,bir sınıfın yalnızca run()
adlı metodunu kullanmak yeterlidir.
class ProcessCounter implements Runnable{
@Override
public void run() {
//Yürütülecek işlemler
}
}
*Not:Thread sınıfını genişleten bir sınıf oluşturarak Bir kanal
oluşturulabilir.O sınıfa run () metodunu ezerek bunu gercekleştirebiliriz.
class ProcessCounter extends Thread{
@Override
public void run() {
//Yürütülecek işlemler
}
}
4. * @author ozaytunctan13
*/
public class ProcessCounter implements Runnable {
int counter;
public ProcessCounter(int counter) {
this.counter = counter;
}
@Override
public void run() {
for (int i = counter; i <=counter + 5; i++) {
try {
Thread.sleep(200);//Diğer Threadin gecişine izin ver
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ">>" + i);
}
}
public static void main(String[] args) {
ProcessCounter s1 = new ProcessCounter(0);//0-5 arasını yazdır
ProcessCounter s2 = new ProcessCounter(5);//5-10 arasını yazdır
Thread task1 = new Thread(s1, "S1");
Thread task2 = new Thread(s2, "S2");
task1.start();//run()metounu çağır call et
task2.start();//run()metounu çağır call et
}
}
Examples
5. Example:2
public class ProcessCounter extends Thread{
int counter;
public ProcessCounter(String name,int counter) {
this.counter = counter;
new Thread(this, name).start();
//Nesne oluştuktan hemen sonra run()metodunu cağır ve başlat
}
@Override
public void run() {
for (int i = counter; i <=counter + 5; i++) {
try {
Thread.sleep(200);//Diğer Threadin gecişine izin ver
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ">>" + i);
}
}
public static void main(String[] args) {
ProcessCounter s1 = new ProcessCounter("S1",0);//0-5 arasını
yazdır
ProcessCounter s2 = new ProcessCounter("S2",5);//5-10 arasını
yazdır
}
}
6. Task1 Task2 Task3
Kritik Alan
Synchronized
Aynı anda birden fazla işlem aynı alana erişmek istediğinde
kilidi alan sadece o alanda işlemini devam ettirir.Diğer işlemler
bekleme durumunda olur.O alana giren iş parcaçığı işini
bitirdikten sonra kilidi serbest bırakır.Daha sonra bekleyen
tasklar kilidi alıp işlemini yürütür.
Task1 Task2 Task3
7. public class Consumer implements Runnable {
private Buffer buf;
private int m;
private String nameThread;
public Consumer(Buffer buf, String name) {
this.buf = buf;
this.nameThread = name;
new Thread(this, name).start();
}
@Override
public void run() {
int k;
for (int i = 0; i < 10; i++) {
k = buf.get();
System.out.println(nameThread + ":" + k + " Urunu
}
}
}
8. public class Buffer {
private boolean available = false;
private int data;
public synchronized void put(int n) {
while (available) { //Suan veri alınıyorsa bekle avaliable=true
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//avaliable=false; ise uretmeye basla avaliable=true;
this.data = n;
available = true;
notify();
}
public synchronized int get() {
while (!available) { //Uretim yoksa almayı durdur.avaliable=false
try {
wait();
} catch (InterruptedException e) {
}
}
//Uretim yoksa degeri al uretmesi icin sinyal gonder
available = false;
notify();
return data;
}
}
9. public class Producer implements Runnable {
private Buffer buf;
private String nameThread;
private int k;
public Producer(Buffer buf, String name) {
this.buf = buf;
this.nameThread = name;
new Thread(this, name).start();
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
buf.put(++k);
System.out.println(nameThread + ": " + k + " Uretti");
}
}
}
10. ForkJoinPool
Çok büyük işler eğer alt işlere bölünüryosa bu işlemleri alt
gorevlere ayırmak hem performans hemde hız sağlar.
RecursiveTask<V>:Alt Görevler tanımlanınca bir değer döndürür.V
compute() metodunu implement eder.
RecursiveAction:Alt gorevleri tamamlandığında bir değer dönmez
RecursiveTask<V>gorev;
gorev.join():Alt gorevin sonucunu döndür.
gorev.fork():Buyuk görevi alt işlere böl
IF(gorev kcuk ise)
Gorevi hemen yap
Else
Gorevi alt işlere parcalara
Fork():Alt gorevleri işlet
Alt görev sonuclarını döndür
Join();sonucunu döndür
11. Override
otected Integer compute() {
f (gorevSayisi <= 10) {
int ara = 0;//Gorev kucuk hemen yap
for (int i = 0; i < 10; i++) {
ara += uretSayi();
}
System.out.println("Ara Toplam:" + ara);
return ara;
} else {//Gorev Buyuk alt işlere parçala
List<RecursiveTask<Integer>> altGorev = new ArrayList<>();
for (int i = 0; i < gorevSayisi; i += 10) {
Gorev altGorevPaket = new Gorev(10);//10 narlı parçalar halinde
r çağrılıor
altGorevPaket.fork();
altGorev.add(altGorevPaket);
}
int toplam = 0;
for (RecursiveTask<Integer> recursiveTask : altGorev) {
toplam += recursiveTask.join();//alt işlem sonucları al
} return toplam;
blic int uretSayi() {
nt uret = (int) (Math.random() * 100);
System.out.println("Uretilen Sayi: " + uret);
return uret;
12. public static void main(String[] args) throws InterruptedException,
ExecutionException {
System.out.println("Cekirdek sayısı:" +
Runtime.getRuntime().availableProcessors());
ForkJoinPool pool = new
ForkJoinPool(Runtime.getRuntime().availableProcessors());
Gorev gorev = new Gorev(2_000);
int toplam =pool.invoke(gorev);
System.out.println("2_000 Syının Toplamı:"+toplam);
}
Output:
Cıktının bir kesidi:
Ara Toplam:483
Uretilen Sayi: 10
Uretilen Sayi: 71
Uretilen Sayi: 95
Ara Toplam:427
Ara Toplam:489
2_000 Syının Toplamı:99637
ForkJoinPool Main