8 Kasım 2013

Java'da iş Parçacıkları Kullanarak Semafor(Semaphore) ve Yığın(Stack) Örneği

Üretici-Tüketici modeline göre Semafor(Semaphore) ve Yığın(Stack) ile Java iş parçacıklarını kullanarak gerçekleştirelim. N tane iş parçacığı üretici, M tanesi de tüketici olsun. N üretici her biri 100'er tane ürün üretsin (yani yığına eklesin), yığının azami boyutu 10 olsun. Tüketiciler tükettiklerini ekrana yazdırsınlar.

Bunun için Java'da 4 sınıf oluşturacağız. Main, Uretici, Tuketici ve Stack(Yığın sınıfı) Üretici ve Tüketici sınıflarını Thread ile Main sınıfına bağlayacağız.

Main.java
import java.util.concurrent.Semaphore;


public class Main {
    
    public static void main(String[] args) throws InterruptedException{
        Thread[] ureticiler = new Uretici[5];
        Thread[] tuketiciler = new Tuketici[10];
        
        Yigin<Integer> y = new Yigin<Integer>(10);
        Semaphore[] semaforlar = new Semaphore[3];
        
        semaforlar[0] = new Semaphore(1);        // KILIT
        semaforlar[1] = new Semaphore(10);        // BOS
        semaforlar[2] = new Semaphore(0);        // DOLU
        
        for(int i = 0; i < ureticiler.length; i++){
            ureticiler[i] = new Uretici(y,  semaforlar, i);
            ureticiler[i].start();
        }
        
        for(int i = 0; i < tuketiciler.length; i++){
            tuketiciler[i] = new Tuketici(y, semaforlar, i);
            tuketiciler[i].start();
        }
        
        for(int i = 0; i < ureticiler.length; i++)
            ureticiler[i].join();
        
        for(int i = 0; i < tuketiciler.length; i++)
            tuketiciler[i].join();
    }
}

Tuketici.java
import java.util.Random;
import java.util.concurrent.Semaphore;


public class Tuketici  extends Thread{

    private Yigin<Integer> y;
    private Semaphore[] k;
    private int kimlik;
    
    Tuketici(Yigin<Integer> y, Semaphore[] k, int kimlik){
        this.y  = y;
        this.k = k;
        this.kimlik = kimlik;
    }
    
    public void run(){
        
        try{
            for(int i = 0; i < 50; i++){        // HER URUN ICIN
                
                k[2].acquire();            // WAIT DOLU
                
                k[0].acquire();            // WAIT KILIT
        
                System.out.println(y.pop() + " kimlik " + kimlik);        // TUKET
            
                k[0].release();            // POST KILIT
                
                k[1].release();            // POST BOS    
            }
        }catch(InterruptedException e){
            e.printStackTrace();
        }    
    }
}

Uretici.java
import java.util.Random;
import java.util.concurrent.Semaphore;


public class Uretici  extends Thread{

    private Yigin<Integer> y;
    private Semaphore[] k;
    private int kimlik;
    
    Uretici(Yigin<Integer> y, Semaphore[] k, int kimlik){
        this.y  = y;
        this.k = k;
        this.kimlik = kimlik;
    }
    
    public void run(){
        Random r = new Random();
        
        for(int i = 0; i < 100; i++){    // HER URUN ICIN
            int n = r.nextInt(1000);

            try{
                k[1].acquire();            // WAIT BOS
                
                k[0].acquire();            // WAIT KILIT
            
                if(y.push(n) == 0){
                    System.out.println("Uretiliyor " + n + " kimlik " + kimlik);        // URET
                }else
                    System.out.println("Uretilemedi!!!!!!!!!");
                
                k[0].release();            // POST KILIT
                
                k[2].release();            // POST DOLU
            
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

Yigin.java
import java.util.ArrayList;

public class Yigin <T>{
    private int tepe;
    private ArrayList<T> dizi;
    private int boyut;
    
    public Yigin(int boyut){
        this.boyut = boyut;
        dizi = new ArrayList<T>();
        tepe = 0;
    }
    
    public boolean doluMu(){
        return (dizi.size() >= boyut);
    }
    
    public boolean bosMu(){
        return (dizi.size() == 0);
    }
    
    public int push(T deger){
        if(doluMu() == false){
            dizi.add(tepe, deger);
            tepe++;
            return 0;
        }else return -1;
    }
    
    public T pop(){
        if(bosMu() == false){
            tepe--;
            return dizi.remove(tepe);
        }else
            return null;
    }
    
    public static void main(String[] args){
        Yigin<String> y = new Yigin<String>(5);
        
        y.push("abc");
        y.push("def");
        y.push("ghi");
        
        System.out.println(y.pop());
        System.out.println(y.pop());
        System.out.println(y.pop());
    }
}

Coded by Erchan Aptoula