Modul D

 Laporan Sistem Operasi


Modul D



Disusun Oleh :

Riska Haqika Situmorang
2208107010086








 

JURUSAN INFORMATIKA
FAKULTAS MATEMATIKA DAN ILMU PENGETAHUAN ALAM
UNIVERSITAS SYIAH KUALA
DARUSSALAM, BANDA ACEH
 2023




Deadlock in Java

 1.TestDeadlockExample1.java

  • public class TestDeadlockExample1 adalah deklarasi kelas utama.
  • final String resource1 = "ratan jaiswal"  Mendefinisikan variabel string resource1 dengan nilai "ratan jaiswal".
  • final String resource2 = "vimal jaiswal"  Mendefinisikan variabel string resource2 dengan nilai "vimal jaiswal".
  • Thread t1 = new Thread()  Membuat objek Thread t1 dengan mendefinisikan metode run() secara anonim.
  • synchronized (resource1)  Memulai blok synchronized dengan resource1 sebagai objek kunci. Ini mengunci resource1.
  • System.out.println("Thread 1: locked resource 1")  Mencetak pesan bahwa "Thread 1: locked resource 1".
  • try { Thread.sleep(100);} catch (Exception e) {} Thread t1 tidur selama 100 milidetik (simulasi)
  • synchronized (resource2) {: Memulai blok synchronized dengan resource2 sebagai objek kunci. Thread t1 mencoba mengunci resource2.
  • System.out.println("Thread 1: locked resource 2"); Mencetak pesan bahwa "Thread 1: locked resource 2".

  • Thread t2 = new Thread()  Membuat objek Thread t2 dengan mendefinisikan metode run() secara anonim.
  • synchronized (resource2)  Memulai blok synchronized dengan resource2 sebagai objek kunci. Ini mengunci resource2.
  • System.out.println("Thread 2: locked resource 2"); Mencetak pesan bahwa "Thread 2: locked resource 2".
  • try { Thread.sleep(100);} catch (Exception e) {}: Thread t2 tidur selama 100 milidetik (simulasi).
  • synchronized (resource1) {: Memulai blok synchronized dengan resource1 sebagai objek kunci. Thread t2 mencoba mengunci resource1.
  • System.out.println("Thread 2: locked resource 1"); Mencetak pesan bahwa "Thread 2: locked resource 1".
  • t1.start();: Memulai eksekusi t1.
  • t2.start();: Memulai eksekusi t2.

    Kode ini menciptakan dua thread, t1 dan t2, yang mencoba mengunci dua sumber daya (resources) yang berbeda, yaitu resource1 dan resource2, tetapi dalam urutan yang berbeda. Hal ini dapat menyebabkan deadlock, di mana kedua thread saling menunggu satu sama lain untuk melepaskan sumber daya yang mereka kunci. Kedua thread akan terjebak dan tidak akan melanjutkan eksekusi, sehingga tidak akan mencetak pesan "Thread 1: locked resource 2" atau "Thread 2: locked resource 1". Kode ini adalah contoh yang mengilustrasikan situasi deadlock dalam multithreading.


Output dari kode diatas  menciptakan dua thread, t1 dan t2, yang mencoba mengunci dua sumber daya, yaitu resource1 dan resource2, dalam urutan yang berbeda. Namun, karena thread t1 mengunci resource1 terlebih dahulu dan thread t2 mengunci resource2 terlebih dahulu, mereka akan saling menunggu satu sama lain untuk melepaskan sumber daya yang mereka kunci. Ini dapat menyebabkan deadlock, di mana kedua thread terjebak dan tidak akan melanjutkan eksekusi. Akibatnya, pesan "Thread 1: locked resource 2" dan "Thread 2: locked resource 1" tidak akan dicetak, dan program mungkin akan terjebak dalam keadaan tidak responsif. Deadlock adalah situasi yang harus dihindari dalam pemrograman multithread, dan perlu diterapkan strategi yang tepat untuk menghindari deadlock, seperti mengunci sumber daya dalam urutan yang konsisten atau menggunakan mekanisme lain untuk mengelola sumber daya bersama.


 2. DeadlockSolved.java


  • public class DeadlockSolved  Ini adalah deklarasi kelas utama.
  • DeadlockSolved test = new DeadlockSolved();: Membuat objek DeadlockSolved dengan nama test.
  • final resource1 a = test.new resource1(); Membuat objek resource1 dengan nama a melalui objek test.
  • final resource2 b = test.new resource2(); Membuat objek resource2 dengan nama b melalui objek test.
  • Runnable b1 = new Runnable()  Membuat objek Runnable dengan mendefinisikan metode run() secara anonim untuk Thread-1.
  • synchronized (b) {: Memulai blok synchronized dengan b sebagai objek kunci. Ini mengunci resource2.
  • Thread.sleep(100);: Menambahkan keterlambatan agar kedua thread memiliki kesempatan untuk mencoba mengunci sumber daya sebelumnya.
  • synchronized (a) {: Memulai blok synchronized dengan a sebagai objek kunci. Thread-1 memiliki resource1 tetapi memerlukan resource2 juga.
  • System.out.println("In block 1");: Mencetak pesan "In block 1" jika thread berhasil melewati blok ini


  • Runnable b2 = new Runnable()  Membuat objek Runnable dengan mendefinisikan metode run() secara anonim untuk Thread-2.
  • synchronized (b)  Memulai blok synchronized dengan b sebagai objek kunci. Ini mengunci resource2.
  • synchronized (a)  Memulai blok synchronized dengan a sebagai objek kunci. Thread-2 memiliki resource2 tetapi memerlukan resource1 juga.
  • System.out.println("In block 2");: Mencetak pesan "In block 2" jika thread berhasil melewati blok ini.
  • new Thread(b1).start(); Membuat dan memulai Thread-1 yang menjalankan b1.
  • new Thread(b2).start(); Membuat dan memulai Thread-2 yang menjalankan b2.




  • private class resource1  adalah deklarasi kelas dalam kelas utama, yang mewakili resource1.
  • private class resource2   adalah deklarasi kelas dalam kelas utama, yang mewakili resource2

Kode ini menciptakan dua thread, Thread-1 dan Thread-2, yang mencoba mengunci dua sumber daya yang berbeda, resource1 dan resource2, dalam urutan yang sama. Kode ini menghindari deadlock dengan mengunci sumber daya dalam urutan yang sama untuk kedua thread. Sebagai hasilnya, kedua thread dapat beroperasi tanpa deadlock dan mencetak pesan "In block 1" dan "In block 2".


    Output dari kode diatas mencetak pesan "In block 1" dan "In block 2" secara bergantian oleh dua thread, yaitu Thread-1 dan Thread-2. Kedua thread mencoba mengunci dua sumber daya yang berbeda, resource1 dan resource2, dalam urutan yang sama, sehingga menghindari deadlock. Pertama, Thread-1 mengunci resource2 terlebih dahulu dan kemudian resource1, sementara Thread-2 mengunci resource2 terlebih dahulu dan kemudian resource1. Karena kunci sumber daya diambil dalam urutan yang konsisten, kedua thread berhasil mengakses sumber daya yang mereka butuhkan tanpa saling menghambat. Oleh karena itu, pesan "In block 1" dan "In block 2" dicetak secara bergantian sebagai indikasi bahwa kedua thread dapat beroperasi dengan aman dan tanpa deadlock.



 3. ProducerConsumerTest.Java

  • class CubbyHole  Ini adalah deklarasi kelas CubbyHole yang akan digunakan untuk berbagi data antara produsen dan konsumen.
  • private char contents; Variabel contents digunakan untuk menyimpan isi dari CubbyHole.
  • private boolean available = false; Variabel available menunjukkan ketersediaan data dalam CubbyHole.
  • public synchronized char get()  Ini adalah metode get() yang digunakan oleh konsumen untuk mengambil isi dari CubbyHole. Ini disinkronkan untuk menghindari konflik antara thread.
  • while (!available) Perulangan while menunggu sampai data tersedia (ketika available adalah true).
  • wait();: Jika data tidak tersedia, konsumen akan menunggu (wait()) sampai produsen memberi tahu bahwa data sudah tersedia.
  • available = false;: Setelah mengambil data, available diatur kembali ke false untuk menandakan bahwa data sudah diambil.
  • notifyAll();: Ini memberi tahu semua thread yang mungkin menunggu (dalam metode put()) bahwa data sudah tersedia.
  • return contents;: Mengembalikan isi yang diambil oleh konsumen.
  • public synchronized void put(char value) {: Ini adalah metode put() yang digunakan oleh produsen untuk menaruh isi ke dalam CubbyHole. Seperti get(), ini juga disinkronkan.
  • while (available) {: Perulangan while menunggu sampai data diambil oleh konsumen (ketika available adalah false).
  • wait();: Jika data masih tersedia, produsen akan menunggu (wait()) sampai konsumen memberi tahu bahwa data sudah diambil.
  • contents = value;: Menyimpan nilai yang akan dimasukkan ke dalam CubbyHole.
  • available = true;: Mengatur available ke true untuk menandakan bahwa data sudah tersedia.
  • notifyAll();: Memberi tahu semua thread yang mungkin menunggu (dalam metode get()) bahwa data sudah tersedia.

  • class Producer extends Thread adalah deklarasi kelas Producer yang merupakan thread produsen.
  • public Producer(CubbyHole c)  Konstruktor Producer menerima objek CubbyHole yang akan digunakan untuk berbagi data.
  • public void run() {: Ini adalah metode run() yang akan dijalankan saat thread Producer dimulai.
  • cubbyhole.put(c);: Produsen menggunakan metode put() untuk menaruh karakter c ke dalam CubbyHole.
  • System.out.println("Producer put: " + c); Mencetak pesan yang menunjukkan karakter yang dimasukkan oleh produsen.
  • sleep((int)(Math.random() * 100)); Menambahkan keterlambatan acak antara 0 hingga 100 milidetik sebelum memasukkan karakter berikutnya ke dalam CubbyHole


  • class Consumer extends Thread {: Ini adalah deklarasi kelas Consumer yang merupakan thread konsumen.
  • public Consumer(CubbyHole c) {: Konstruktor Consumer menerima objek CubbyHole yang akan digunakan untuk berbagi data.
  • public void run() {: Ini adalah metode run() yang akan dijalankan saat thread Consumer dimulai.
  • char value = cubbyhole.get();: Konsumen menggunakan metode get() untuk mengambil karakter dari CubbyHole.
  • System.out.println("Consumer got: " + value); Mencetak pesan yang menunjukkan karakter yang diambil oleh konsumen.



  • public class ProducerConsumerTest {: Ini adalah deklarasi kelas utama yang akan menjadi tempat eksekusi utama program.
  • CubbyHole c = new CubbyHole(); Membuat objek CubbyHole yang akan digunakan oleh produsen dan konsumen untuk berbagi data.
  • Producer p1 = new Producer(c); Membuat objek Producer dengan menggunakan objek CubbyHole sebagai parameter konstruktor.
  • Consumer c1 = new Consumer(c); Membuat objek Consumer dengan menggunakan objek CubbyHole sebagai parameter konstruktor.
  • p1.start();: Memulai thread Producer.
  • c1.start();: Memulai thread Consumer

    Kode diatas adalah contoh implementasi model produsen-konsumen menggunakan Java dengan sinkronisasi untuk memastikan bahwa produsen dan konsumen dapat berinteraksi dengan aman. Proses produsen memasukkan karakter dari 'A' hingga 'Z' ke dalam CubbyHole, sementara konsumen mengambil karakter tersebut satu per satu.


    Output di atas adalah hasil dari eksekusi program "Producer-Consumer". Produsen (Producer) memasukkan karakter dari 'A' hingga 'Z' ke dalam CubbyHole, dan konsumen (Consumer) mengambil karakter-karakter tersebut secara bergantian. Setiap karakter yang dimasukkan oleh produsen akan segera diambil oleh konsumen, sehingga hasil cetakan menunjukkan urutan karakter 'A' sampai 'Z'. Keduanya beroperasi secara bergantian dan sinkronized sehingga tidak ada konflik akses ke CubbyHole.


LAMPIRAN :

 1. TestDeadlockExample1.java

public class TestDeadlockExample1 {  
  public static void main(String[] args) {  
    final String resource1 = "ratan jaiswal";  
    final String resource2 = "vimal jaiswal";  
    // t1 tries to lock resource1 then resource2  
    Thread t1 = new Thread() {  
      public void run() {  
          synchronized (resource1) {  
           System.out.println("Thread 1: locked resource 1");  
  
           try { Thread.sleep(100);} catch (Exception e) {}  
  
           synchronized (resource2) {  
            System.out.println("Thread 1: locked resource 2");  
           }  
         }  
      }  
    };  
  
    // t2 tries to lock resource2 then resource1  
    Thread t2 = new Thread() {  
      public void run() {  
        synchronized (resource2) {  
          System.out.println("Thread 2: locked resource 2");  
  
          try { Thread.sleep(100);} catch (Exception e) {}  
  
          synchronized (resource1) {  
            System.out.println("Thread 2: locked resource 1");  
          }  
        }  
      }  
    };  
  
      
    t1.start();  
    t2.start();  
  }  
}       


 2. DeadlockSolved.java

public class DeadlockSolved {  
   
    public static void main(String ar[]) {  
        DeadlockSolved test = new DeadlockSolved();  
   
        final resource1 a = test.new resource1();  
        final resource2 b = test.new resource2();  
   
   // Thread-1  
Runnable b1 = new Runnable() {  
    public void run() {  
        synchronized (b) {  
            try {  
                /* Adding delay so that both threads can start trying to lock resources */  
                Thread.sleep(100);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
            // Thread-1 have resource1 but need resource2 also  
            synchronized (a) {  
                System.out.println("In block 1");  
            }  
        }  
    }  
};  
   
// Thread-2  
Runnable b2 = new Runnable() {  
    public void run() {  
        synchronized (b) {  
            // Thread-2 have resource2 but need resource1 also  
            synchronized (a) {  
                System.out.println("In block 2");  
            }  
        }  
    }  
};  
  
   
        new Thread(b1).start();  
        new Thread(b2).start();  
    }  
   
    // resource1  
    private class resource1 {  
        private int i = 10;  
   
        public int getI() {  
            return i;  
        }  
   
        public void setI(int i) {  
            this.i = i;  
        }  
    }  
   
    // resource2  
    private class resource2 {  
        private int i = 20;  
   
        public int getI() {  
            return i;  
        }  
   
        public void setI(int i) {  
            this.i = i;  
        }  
    }  
}  


 3. ProducerConsumerTest.Java

class CubbyHole {

    private char contents;

    private boolean available = false;


    public synchronized char get() {

        while (!available) {

            try {

                wait();

            } catch (InterruptedException e) { }

        }

        available = false;

        notifyAll();

        return contents;

    }


    public synchronized void put(char value) {

        while (available) {

            try {

                wait();

            } catch (InterruptedException e) { }

        }

        contents = value;

        available = true;

        notifyAll();

    }

}


class Producer extends Thread {

    private CubbyHole cubbyhole;


    public Producer(CubbyHole c) {

        cubbyhole = c;

    }


    public void run() {

        for (char c = 'A'; c <= 'Z'; c++) {

            cubbyhole.put(c);

            System.out.println("Producer put: " + c);

            try {

                sleep((int)(Math.random() * 100));

            } catch (InterruptedException e) { }

        }

    }

}


class Consumer extends Thread {

    private CubbyHole cubbyhole;


    public Consumer(CubbyHole c) {

        cubbyhole = c;

    }


    public void run() {

        for (int i = 0; i < 26; i++) {

            char value = cubbyhole.get();

            System.out.println("Consumer got: " + value);

        }

    }

}


public class ProducerConsumerTest {

    public static void main(String[] args) {

        CubbyHole c = new CubbyHole();

        Producer p1 = new Producer(c);

        Consumer c1 = new Consumer(c);


        p1.start();

        c1.start();

    }

}



Komentar