Anda di halaman 1dari 22

LAPORAN PRAKTIKUM DESAIN APLIKASI DAN MULTIMEDIA MODUL KE-1 COLLECTION AND THREAD

OLEH: SUSI EKAWATI (201110370311121)

LABORATORIUM PEMROGRAMAN PROGRAM STUDI TEKNIK INFORMATIKA FAKULTAS TEKNIK UNIVERSITAS MUHAMMADIYAH MALANG 2013

I.

TUJUAN Setelah mempelajari modul ini peserta diharapkan dapat: Memahami tentang interface Collection pada Java Mengerti tentang pembuatan Vector, ArrayList dan LinkedList. Membuat dan mengelolah Thread Memahami proses sinkronisasi data Menggunakan method Wait dan Notify TEORI DASAR COLLECTION Collection atau sering juga disebut sebagai container adalah sebuah object sederhana yang menampung lebih dari satu elemen di dalam satu kesatuan. Collection digunakan untuk menyimpan,mengambil dan memanipulasi data, juga mentransmisikan data dari satu method ke method lain. Collection khusus merepresentasikan data item dari bentuk yang sebenarnya seperti Poker (kumpulan dari kartu), direktori (kumpulan dari file atau folder), kotak surat (kumpulan dari surat-surat), dll. SDK tidak menyediakan implementasi built-in yang lain dari interface ini tetapi mengarahkan subinterfaces, Set interfaces dan List interfaces diperbolehkan. Sekarang, apa perbedaan dari kedua interface tersebut. Set merupakan collection yang tidak dipesan dan tidak ada penggandaan didalamnya. Sementara itu, list merupakan collection yang dipesan dari elemen-elemen dimana juga diperbolehkannya penggandaan. HashSet, LinkedHashSet dan TreeSet adalah implementasi class dari Set interfaces. ArrayList, LinkedList dan Vector merupakan implementasi class dari List interfaces. <root interface> Collection <interface> Set <implementing classes> HashSet LinkedHashSet TreeSet <interface> List <implementing classes> ArrayList LinkedList Vector

II.

A. Vektor Vektor adalah implementsi dari dinamis array, yang hampir sama dengan ArrayList perbedaanya adalah vector mempunyai method yang bukan turunan dari collection framework. Pada Java 2 vektor diperluas lagi dengan mengextends AbstractList dan mengimplementasikan List interface yang sangat mendukung collection. Dibawah ini adalah konstruktor dari Vector.

Vector(); Vector(int size); Vector(int size,int incr);

Konstruktor pertama adalah konstruktor default yang menginialisasikan ukuran sebanyak 10 elemen. Konstruktor kedua yaitu menentukan jumlah elemen yang akan digunakan. Konstruktor yang ketiga yaitu menentukan ukuran awal dan apabila ukurannya full maka akan ditambah lagi sebanyak incr. Dibawah ini beberapa method yang disediakan oleh class Vector.

Method addElement(<object>)

Keterangan Digunakan untuk menambahkan object ke dalam Vektor. data

elementAt(<index>)

Method ini berfungsi untuk mengambil elemen berdasarkan nomor index yang dimasukan. Berfungsi untuk mengambil nilai berupa object yang paling terakhir di tambahkan dari sebuah object vektor. Berfungsi untuk mengambil nilai berupa object pertama yang di tambahkan dari sebuah object vektor. Digunakan untuk menghapus seluruh elemen yang tersimpan dalam object vector. Memeriksa apakah verktor yang digunakan berisi elemen atau tidak. Jika ada data maka akan mengembalikan nilai boolean berupa false.

lastElement()

firstElement()

clear()

isEmpty()

B. Array List ArrayList hampir mirip seperti vektor. Pada JDK 1.1 ArrayList 3-4 kali lebih cepat dari pada Vektor, sedangkan pada JDK 1.1.4 ArrayList 40 kali lebih cepat daripada vektor. Pembuatan Object ArrayList dapat dilihat seperti dibawah ini.

ArrayList al=new ArrayList();

Tidak seperti array dimana untuk mengambil ukuran menggunakan <array>.length, ArrayList menggunakan al.size(). Dibawah ini adalah beberapa method-method yang dapat digunakan pada ArrayList.

Method add(<object>)

Keterangan Digunakan untuk menambahkan data object ke dalam ArrayList. Method ini menyediakan dua parameter untuk menambahkan sebuah object dengan menentukan nomor index elemennya. Method get adalah method yang disediakan oleh ArrayList untuk mengambil sebuah object berdasarkan nomor indexnya. Mothod ini berfungsi untuk menghapus elemen ArrayList berdasarkan nomor indexnya. Digunakan untuk memeriksa apakah object ArayList yang dibuat kosong atau tidak. Menghapus semua elemen yang ada di dalam object ArrayList.

add(<index>,<object>)

get(<index>)

remove(<index>)

isEmpty()

clear()

C. LinkedList LinkedList mengimplementasi interface List. LinkedList juga memperbolehkan elemennya menggunakan null. Pertama yang harus kita lakukan adalah membuat object LinkedList seperti dibawah ini:

LinkedList ll=new LinkedList();

Ada beberapa method yang disediakan class LinkedList antara lain adalah sebagai berikut:

Method add(<object>) size()

Keterangan Digunakan untuk menambahkan object ke dalam LinkedList. data

Mengambil jumlah elemen pada object LinkedList Mengambil nilai elemen nomor index yang ada LinkedList berdasarkan pada object

get(<index>) addFirst() addLast() getFirst() getLast() clear()

Menambahkan object pada elemen awal Menambahkan object pada elemen akhir Mengambil nilai elemen pertama Mengambil nilai elemen terakhir Menghapus semua nilai elemen pada object LinkedList Method remove tanpa parameter akan menghapus elemen pertama Parameter akan menunjukan mana yang akan dihapus elemen

remove()

remove(<index>)

THREAD Sebuah thread dapat dengan mudah anda buat dan jalankan dengan cara membuat instance dari object Thread dan memanggil method start(). Thread myThread= new Thread(); myThread.start(); Saat anda menjalankan kode diatas tentu saja tidak akan ada yang terjadi selain aplikasi anda jalan dan langsung mati. Ketika anda menjalankannya JVM akan membuat sebuah thread baru dan secara default akan memanggil method run(), dalam hal ini run() kosong sehingga thread akan langsung mati. Berikut ini adalah cara memberikan tugas kepada thread : 1. meng-extends class Thread 2. meng-implements class Runnable 3. menggunakan innerclass tanpa nama

Meng-extends Class Thread Cara cepat memberikan tugas kepada thread adalah dengan mengoverride method run().

public class MyThread extends Thread { public void run(){ System.out.println(saya adalah thread); } }

Berikutnya yang perlu anda lakukan adalah membuat instance dari object Thread dan memanggil method start() sama seperti bahasan sebelumnya. Thread myThread = new MyThread(); myThread.start();

Meng-implements Class Runnable meng-extends class Thread sangat mudah, tetapi mungkin anda tidak ingin menulis class baru setiap kali ingin menggunakan thread. Contoh nya anda mungkin sedang mengextends class JFrame dalam aplikasi GUI, dan ingin menggunakan thread, solusinya anda bisa menggunakan interface Runnable(). public class MyThread extends JFrame implements Runnable { public MyThread(){ Thread t=new Thread(this); t.start(); } public void run(){ System.out.println(saya adalah thread); } } Dalam kode diatas MyThread membuat instance dari object thread pada konstruktor dengan object Runnable (dalam hal ini class MyThread sendiri), dan selanjutnya memulainya. Menggunakan Inner Class Tanpa Nama Suatu saat mungkin anda ingin membuat sebuah thread tanpa harus membuat class baru ataupun mengimplements Runnable. Anda dapat melakukanya dengan dengan cara membuat inner class. new Thread() { public void run() { System.out.println("saya adalah Thread"); } }.start(); Cara ini tidak lazim digunakan. Dapat anda bayangkan jika kode dalam method run() semakin besar Menggunakan sleep() Suatu saat anda perlu menghentikan sementara sebuah thread, untuk itu anda bisa menggunakan method sleep(). try{ Thread.sleep(1000); }catch(Exception e){} Kode diatas akan membuat thread anda berhenti selama 1 detik (1000 milidetik). Selama thread anda dalam kondisi sleep, thread anda tidak memerlukan kerja cpu. Kondisi sleep pada sebuah thread akan dimanfaatkan untuk menjalankan thread lainya. Menghentikan Thread Ada dua cara yang bisa anda lakukan untuk menghentikan sebuah thread. Pertama adalah menggunakan flag (tanda) dan yang kedua adalah menggunakan method interrupt(). Jika anda mempelajari thread anda mungkin bingung, mengapa tidak menggunakan method

stop(). Ketika anda menggunakan method stop(), maka bersiap-siaplah melihat program anda tak terkendali atau bahkan mati. Method stop() mengakibatkan thread lain selain thread yang anda inginkan berhenti. Menggunakan Flag(tanda) Cara yang paling banyak digunakan untuk menghentikan sebuah thread adalah menggunakan variabel penanda. Thread dapat memeriksa variabel tersebut secara berkala untuk memastikan kondisi berhenti. public class MyThread extends JFrame implements Runnable { private volatile boolean done=false; public MyThread(){ Thread t=new Thread(this); t.start(); } public void run(){ while(!done){ System.out.println(saya adalah thread); } } Public void setDone(){ done=true; } Dengan kode diatas secara berkala thread akan memeriksa kondisi penanda, ketika penanda bernilai true maka thread tidak lagi dijalankan. Menggunakan interupsi Cara lain yang dapat anda gunakan adalah dengan menginterrupsi sebuah thread. Cara ini biasa digunakan pada sistem blocking. Sistem blocking adalah sistem yang mem-block jalannya sistem sampai sebuah kunci di lepaskan. Contoh sistem blocking salah satunya pola penerimaan koneksi jaringan (pembahasan jaringan akan di jelaskan pada bab berikutnya). Pada teknik penghentian menggunakan flag, terdapat sebuah kondisi yang memungkinkan sistem kehilangan/terlambat menerima informasi. Contohnya ketika sebuah thread sedang memproses suatu perintah, tiba-tiba flag di set. Kondisi ini setidaknya membuat thread harus menyelesaikan proses tersebut dan baru akan menghentikan proses pada loop berikutnya. public class MyThread extends JFrame implements Runnable { private volatile boolean done=false; Thread t; public MyThread(){ t=new Thread(this); t.start(); } public void run(){ while(!t.isInterrupted()){ System.out.println(saya adalah thread); }

} } Dengan method interrupt(), thread akan di paksa berhenti dan mengabaikan proses yang sedang berjalan. Penggunaan method interrupt() dapat dengan mudah dilakukan dengan memanggil method tersebut. Sinkronisasi data Apa yang terjadi ketika dua thread menggunakan variabel yang sama? Bisa saja salah satu thread mencoba mengkases data yang telah di hapus oleh thread lainya. Dalam hal ini kedua thread harus di sinkronisasi sehingga masing-masing thread tidak kehilangan informasi. Sinkronisasi berfungsi mengunci sebuah object, ketika sebuah object terkunci maka tidak ada yang bisa dilakukan terhadap object tersebut sebelum kunci di lepas. Anggaplah anda mempunyai dua buah thread yang mengakses variabel dari object yang sama. Suatu saat thread a mencoba mengambil data dalam variabel tersebut ,sementara thread b mencoba mengubah data tersebut . public class GamePlayer { public int getLives() { return lives; } public void setLives(int l) { lives = l; } private int lives; Asumsikan kedua buah thread ingin mengakses object gamePlayer yang sama. //Thread A int lives=gamePlayer.getLives(); gamePlayer.setLives(lives-1) //Thread B int lives=gamePlayer.getLives(); gamePlayer.setLives(lives-1); Kondisi yang diinginkan adalah variabel Lives mendapatkan pengurangan 2 kali. Namun ketika Thread A dan B mengakses variabel Lives dalam waktu yang bersamaan kemudian menguranginya maka yang terjadi variabel Lives hanya akan mengalami satu pengurangan. Untuk memperbaiki kondisi tersebut kita bias menggunakan kata kunci synchronized; //Thread A Synchronized(gamePlayer){ int lives=gamePlayer.getLives(); gamePlayer.setLives(lives-1); } //Thread B Synchronized(gamePlayer){

int lives=gamePlayer.getLives(); gamePlayer.setLives(lives-1); } Menggunakan wait dan notify Sampai dengan saat ini anda telah mempelajari bagaimana thread bekerja secara mandiri. Pada kenyataan suatu saat anda perlu mengkomunikasikan dua atau lebih thread. Katakanlah anda mempunyai dua buah thread yang anda gunakan dalam komunikasi jaringan, thread A dan thread B. Thread A akan mengirimkan pesan manakala thread B selesai mengisi pesan. // Thread A public void waitForMessage() { while (hasMessage == false) { Thread.sleep(100); } } // Thread B public void setMessage(String message) {..... hasMessage = true; } Perhatikan kode diatas. Secara berkala thread A akan mengecek kondisi hasMessage. Jika hasMessage tidak di set pada pengecekan terkini maka berikutnya thread akan sleep selama 100 ms. Kode tersebut memang bekerja, tetapi apa yang terjadi jika hasMessage di set ketika Thread A dalam keadaan sleep? Thread A akan kehilangan atau setidaknya terlambat menerima informasi. Dengan method wait dan notify hal ini dapat di selesaikan. Thread a cukup menunggu sampai dengan thread B mengirimkan sinyal bahwa pesan telah siap. // Thread A public synchronized void waitForMessage() { try { wait(); } catch (InterruptedException ex) { } } // Thread B public synchronized void setMessage(String message) { ... notify(); } Seperti yang kita lihat diatas apabila method waitForMessage() di panggil maka secara otomatis program akan berhenti secara mendadak untuk menunggu method setMessage() dipanggil atau dijalankan.

III.

HASIL PRAKTIKUM

Percobaan 1: Membuat Class PercobaanVektor package modul1; import java.awt.Graphics; import java.util.Vector; import javax.swing.JFrame; public class PercobaanVector extends JFrame{ public static void main(String[] args) { new PercobaanVector(); } Vector vk; PercobaanVector () { vk = new Vector (); vk.addElement("test Vektor"); vk.addElement("Coba Add Lagi"); this.setDefaultCloseOperation(this.EXIT_ON_CLOSE); this.setSize(500, 500); this.setVisible(true); setTitle("Test Vector"); } public void paint(Graphics g){ g.clearRect(0,0, 500, 500); g.drawString("Jumlah Elemen Vektor :"+String.valueOf(vk.size()), 10, 50); g.drawString("Elemen Vektor ke-0 :"+vk.elementAt(0), 10, 100); g.drawString("Elemen Vektor Ke-1 :"+vk.elementAt(1), 10, 150); g.drawString("Elemen Pertama :"+vk.firstElement(),10, 200); g.drawString("Elemen Terakhir :"+vk.lastElement(), 10, 250); g.drawString("Mothod isEmpty :"+vk.isEmpty(), 10, 300); vk.clear(); g.drawString("Method isEmpty :"+vk.isEmpty(), 10, 350); } }

Output:

Penjelasan : Pada percobaan 1 terdapat method addElement(<object>) digunakan untuk menambahkan data object ke dalam Vektor. Kemudian akan dipanggil oleh method elementAt(<index>) untuk mengambil elemen berdasarkan nomor index yang dimasukkan(output).

Percobaan 2: Membuat Class ArrayList package modul1; import java.awt.Graphics; import java.util.ArrayList; import javax.swing.JFrame;

public class ArrayListCoba extends JFrame { public static void main(String[] args) { new ArrayListCoba(); } ArrayList al=new ArrayList(); ArrayListCoba(){ al.add("Test Array List"); al.add(1); al.add(2); this.setDefaultCloseOperation(this.EXIT_ON_CLOSE); this.setSize(500, 500); this.setVisible(true); setTitle("Test ArrayList"); } public void paint(Graphics g){ g.clearRect(0,0, 500, 500); g.drawString("Banyaknya Elemen di ArrayList adalah :"+String.valueOf(al.size()), 10, 50); g.drawString("Isinya Adalah Sebagai berikut :", 10, 100); g.drawString("Elemen ke-0 :"+(String) al.get(0), 10, 150); g.drawString("Element ke-1:"+String.valueOf(al.get(2)), 10, 200); g.drawString("Elemen Ke-2 :"+String.valueOf(al.get(1)), 10, 250); al.remove(0); al.add(1, "Test"); g.drawString("Banyaknya Elemen di ArrayList Setelah di Hapus adalah :"+String.valueOf(al.size()), 10, 300); g.drawString("Elemen Ke-1 :"+String.valueOf(al.get(1)), 10, 350); al.clear(); g.drawString("Method isEmpty()"+String.valueOf(al.isEmpty()), 10, 400); } }

Output:

Penjelasan: Pada percobaan 2 terdapat method add(<object>) yang digunakan untuk menambahkan data object ke dalam ArrayList. Kemudian akan dipanggil oleh method add(<index>,<object>) yang menyediakan dua parameter untuk menambahkan sebuah object dengan menentukan nomor index elemennya. Untuk memanggil sebuah object berdasarkan nomor indexnya (output) menggunakan method get(<index>).

Percobaan 3: Membuat Class PercobaanLinkedList package modul1; import java.awt.Graphics; import java.util.LinkedList; import javax.swing.JFrame;

public class PercobaanLinkedList extends JFrame{ public static void main(String args[]){ new PercobaanLinkedList(); } LinkedList ll=new LinkedList(); PercobaanLinkedList(){ ll.add("Test LinkedList"); ll.add("Coba Lagi"); ll.add(10243); this.setDefaultCloseOperation(this.EXIT_ON_CLOSE); this.setSize(500, 500); this.setVisible(true); setTitle("Test LinkedList"); } public void paint(Graphics g){ g.clearRect(0,0, 500, 500); g.drawString("Jumlah Elemen : "+String.valueOf(ll.size()), 10, 50); g.drawString("Elemen Ke-1 : "+ll.get(0), 10, 100); g.drawString("Elemen Ke-2 : "+ll.get(1), 10, 150); g.drawString("Elemen Ke-3 : "+ll.get(2), 10, 200); g.drawString("Method getFirst() : "+ll.getFirst(), 10, 250); g.drawString("Method getLast() : "+ll.getLast(), 10, 300); ll.addLast("Terakhir"); g.drawString("Method getLast() : "+ll.getLast(), 10, 350); ll.remove(); g.drawString("Jumlah Elemen Sekarang : "+String.valueOf(ll.size()), 10, 400); }

Output:

Penjelasan: Pada percobaan 2 terdapat method add(<object>) yang digunakan untuk menambahkan data object ke dalam LinkedList. Untuk memanggil sebuah object berdasarkan nomor indexnya (output) menggunakan method get(<object>).

Percobaan 4: Membuat Class TestThread package modul1; public class TestThread implements Runnable { private Thread th; private boolean running; private long endTime; public TestThread(){ running=true; th = new Thread(this); endTime= System.currentTimeMillis()+10000; } public void run() { int i=0; while(running){ try{ Thread.sleep(1000); }catch(Exception e){} System.out.println("Run "+i); if(System.currentTimeMillis()>endTime) running=false; i++;} } public void start(){ th.start(); } public static void main(String [] agr){ new TestThread().start(); }} Output:

Penjelasan Pada percobaan 4, class TestThread mengimplements class Runnable agar tidak membuat class baru setiap kali menggunakan thread.Hasil output program seperti pada gambar diatas, dimulai Run 0 tampil satu-persatu tiap 1 detik hingga berhenti pada detik ke 10 yang menggunakan method sleep.

Percobaan 5: Membuat Class TestSynchronizedThread package modul1; import java.util.ArrayList; public class TestSynchronizedThread { private ArrayList<String> messageList; private ThreadA ta; private ThreadB tb; public TestSynchronizedThread(){ messageList = new ArrayList<String>(); ta = new ThreadA(); tb = new ThreadB(); } class ThreadA implements Runnable{ Thread th= new Thread(this); public ThreadA(){ th.start(); } public void run() { int i=0; while(i<100){ try{ Thread.sleep(20); }catch(Exception e){}

//synchronized(messageList){ //messageList.add("Hi "+i); messageList.add("Hi "+i); System.out.println("adding message : Hi"+i); i++;} }} class ThreadB implements Runnable{ Thread th= new Thread(this); public ThreadB(){ th.start(); } public void run() { int i=0; while(i<50){ try{ Thread.sleep(40); }catch(Exception e){} /* synchronized(messageList){

for(int j=0;j<messageList.size();j++) System.out.println(messageList.get(j)); } */ for(int j=0;j<messageList.size();j++) System.out.println(messageList.get(j)); i++; } } } public static void main(String arg[]){ new TestSynchronizedThread(); } } Output:

Penjelasan: Pada percobaan 5 terdapat dua thread yaitu thread A dan thread B, dimana saat program dijalankan kedua thread akan bersamaan mengakses perintah dan thread juga bisa kehilangan informasi, akan tetapi jika ada sintaks synchronized (<object>) pada salah satu threads maka itulah yang mendapatkan hak akses kedalam mehod tertentu.

Percobaan 6: Membuat Class TestWaitNotifyThread package modul1; import modul1.TestSynchronizedThread.ThreadB;

public class TestWaitnNotifyThread { private ThreadA ta; private ThreadB tb; private String msg; public TestWaitnNotifyThread(){ ta = new ThreadA(); tb = new ThreadB(); } class ThreadA implements Runnable{ Thread th= new Thread(this); public ThreadA(){ th.start(); } public void run() { int i=0; while(i<100){ try{ Thread.sleep(1000); }catch(Exception e){} setMessage("Hi"+i); i++; } } } class ThreadB implements Runnable{ Thread th= new Thread(this); public ThreadB(){ th.start(); } public void run() { int i=0; while(true){ waitForMessage(); System.out.println(msg); i++; } }

} public synchronized void setMessage(String message) { msg=message; System.out.println("set message : "+msg);

notify(); } public synchronized void waitForMessage() { try { wait(); } catch (InterruptedException ex) { } } public static void main(String arg[]){ new TestWaitnNotifyThread(); } } Output:

Penjelasan Pada percobaan 6 terdapat method waitForMessage(), jika method tersebut dipanggil maka secara otomatis program akan berhenti secara mendadak untuk menunggu method setMessage() dipanggil.

IV.

KESIMPULAN Vector adalah sebuah class yang ditunkan dari interface Collection, yaitu sebuah interface yang digunakan untuk penggolahan data yang bersifat seperti array dinamis, yakni array yang ukurannya secara dinamis dapat membesar ketika data yang dimasukkan melebihi daya tampung. Setiap metode dalam Vector diberih keyword synchronized, sehingga ketika dieksekusi dalam sebuah Thread, maka tak akan terjadi kemacetan Thread. ArrayList adalah sebuah class yang sama dengan Vector dan memiliki fungsi yang hampir sama dengan Vector, namun perbedaannya terletak pada metode yang dimiliki oleh ArrayList. Berbeda dengan Vector, pada ArrayList setiap metode tidak diberi keyword synchronized, sehingga ketika dieksekusi dalam Thread, hal ini dapat mengakibatkan unsafe Thread, alias dapat terjadi tubrukan Thread ketika Thread mencoba untuk memanggil metode ArrayList. Namun bukan berarti ArrayList tidak berguna, karena tak adanya keyword synchronized pada metode ArrayList maka untuk menjalankan metode yang ada pada ArrayList membutuhkan waktu yang lebih singkat dari pada menjalankan metode yang ada pada Vector. Kesimpulannya jika kita ingin membuat array dinamis yang dijalankan menggunakan Thread, maka gunakanlah Vector, sedangkan jika memang proses yang kita butuhkan tidak menggunakan Thread, maka gunakanlah ArrayList agar proses pengolahan array dinamis lebih cepat.