damg jeni 6 modul 1
DESCRIPTION
DAMG JENI 6TRANSCRIPT
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
II. 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 <interface> List
<implementing classes> <implementing classes>
HashSet LinkedHashSet TreeSet ArrayList LinkedList Vector
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 Keterangan
addElement(<object>)
Digunakan untuk menambahkan data
object ke dalam Vektor.
elementAt(<index>)
Method ini berfungsi untuk mengambil
elemen berdasarkan nomor index yang
dimasukan.
lastElement()
Berfungsi untuk mengambil nilai berupa
object yang paling terakhir di tambahkan dari
sebuah object vektor.
firstElement()
Berfungsi untuk mengambil nilai berupa
object pertama yang di tambahkan dari
sebuah object vektor.
clear()
Digunakan untuk menghapus seluruh
elemen yang tersimpan dalam object
vector.
isEmpty()
Memeriksa apakah verktor yang digunakan
berisi elemen atau tidak. Jika ada data maka
akan mengembalikan nilai boolean berupa
false.
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 Keterangan
add(<object>) Digunakan untuk menambahkan data
object ke dalam ArrayList.
add(<index>,<object>)
Method ini menyediakan dua parameter
untuk menambahkan sebuah object
dengan menentukan nomor index
elemennya.
get(<index>)
Method get adalah method yang
disediakan oleh ArrayList untuk
mengambil sebuah object berdasarkan
nomor indexnya.
remove(<index>)
Mothod ini berfungsi untuk menghapus
elemen ArrayList berdasarkan nomor
indexnya.
isEmpty()
Digunakan untuk memeriksa apakah
object ArayList yang dibuat kosong atau
tidak.
clear()
Menghapus semua elemen yang ada di
dalam object ArrayList.
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 Keterangan
add(<object>)
Digunakan untuk menambahkan data
object ke dalam LinkedList.
size() Mengambil jumlah elemen pada object
LinkedList
get(<index>)
Mengambil nilai elemen berdasarkan
nomor index yang ada pada object
LinkedList
addFirst() Menambahkan object pada elemen awal
addLast() Menambahkan object pada elemen akhir
getFirst() Mengambil nilai elemen pertama
getLast() Mengambil nilai elemen terakhir
clear()
Menghapus semua nilai elemen pada
object LinkedList
remove()
Method remove tanpa parameter akan
menghapus elemen pertama
remove(<index>)
Parameter akan menunjukan elemen
mana yang akan dihapus
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.