06 Java Language and OOP Part VI
06 Java Language and OOP Part VI
Part VI
By Hari Christian
Agenda
01 Threads - Basic
02 Threads - How to Obtain Threads
03 Threads - Threads Programming
04 Threads - Advanced
05 Threads - Concurrent
06 Parameters vs Arguments
07 Generics - Basic
08 Generics - What Generic Solves
09 Generics - Generic Code
10 Generics - Generic Interfaces
11 Java Code Convention
Concurrency
Concurrency is the ability to run several
programs or several parts of a program in
parallel
If a time consuming task can be performed
asynchronously or in parallel, this improve the
throughput and the interactivity of the program
Concurrency
A modern computer has several CPU's or
several cores within one CPU
The ability to leverage these multi-cores can be
the key for a successful high-volume application
Process and Threads
A process runs independently and isolated of
other processes
It cannot directly access shared data in other
processes
The resources of the process, e.g. memory and
CPU time, are allocated to it via the operating
system.
Process and Threads
A thread is a so called lightweight process
It can access shared data of other threads in the
same process
Every thread has its own memory cache. If a
thread reads shared data it stores this data in its
own memory cache. A thread can re-read the
shared data
Process and Threads
A Java application runs by default in one
process
Within a Java application you work with several
threads to achieve parallel processing or
asynchronous behavior
Concurrency Issues
Threads can also access shared data. Therefore
you have two basic problems
1. A visibility problem occurs if thread A reads
shared data which is later changed by thread B
and thread A is unaware of this change
2. An access problem can occur if several thread
access and change the same shared data at
the same time
Concurrency Issues
Visibility and access problem can lead to
1. Liveness failure: The program does not react
anymore due to problems in the concurrent
access of data, e.g. deadlocks
2. Safety failure: The program creates incorrect
data
How to Obtain Threads
There are two ways to obtain a new thread of
control in Java
1. Extend the Thread class (only if your class
doesn't already extend some other class)
2. Write a class to implement the
java.lang.Runnable interface and use it in the
Thread constructor
How to Obtain Threads
1. Extend class java.lang.Thread and override
run():
Example:
class Plum extends Thread {
public void run() { /* more code */ }
}
Plum p = new Plum();
p.start();
How to Obtain Threads
2. Implement the Runnable interface
Example:
class Mango implements Runnable {
public void run() { /* more code */ }
}
Mango m = new Mango();
Thread t1 = new Thread(m);
t1.start();
Threads Programming
public class ThreadsTest1 implements Runnable {
public void run() {
for(int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
}
}
public static void main(String[] args) {
ThreadsTest1 r = new ThreadsTest1();
Thread a = new Thread(r, "a");
Thread b = new Thread(r, "b");
Thread c = new Thread(r, "c");
a.start();
b.start();
c.start();
}
}
Threads Programming
public class ThreadsTest2 implements Runnable {
public void run() {
for(int i = 1; i <= 100; i++) {
System.out.println(i % 10 == 0? i + " = KELIPATAN 10" : i);
try {
Thread.sleep(1 * 1000);
} catch (InterruptedException e) {}
}
}
public static void main(String[] args) {
ThreadsTest2 r = new ThreadsTest1();
Thread a = new Thread(r, "a");
a.start();
}
}
Threads Programming
public class Download implements Runnable {
public void run() {
System.out.println("START DOWNLOAD");
for(int i = 0; i < 10; i++) {
System.out.println("DOWNLOADING " + ((i + 1) * 10) + "%");
}
System.out.println("FINISH DOWNLOAD");
}
public void start() {
System.out.println("START DOWNLOAD");
for(int i = 0; i < 10; i++) {
System.out.println("DOWNLOADING " + ((i + 1) * 10) +"%");
}
System.out.println("FINISH DOWNLOAD");
}
}
Threads Programming
public class Upload implements Runnable {
public void run() {
System.out.println("START UPLOAD");
for(int i = 0; i < 10; i++) {
System.out.println(UPLOADING " + ((i + 1) * 10) + "%");
}
System.out.println("FINISH UPLOAD");
}
public void start() {
System.out.println("START UPLOAD");
for(int i = 0; i < 10; i++) {
System.out.println(UPLOADING " + ((i + 1) * 10) +"%");
}
System.out.println("FINISH UPLOAD");
}
}
Threads Programming
public class Report implements Runnable {
public void run() {
System.out.println("START REPORT");
for(int i = 0; i < 10; i++) {
System.out.println(REPORTING " + ((i + 1) * 10) + "%");
}
System.out.println("FINISH REPORT");
}
public void start() {
System.out.println("START REPORT ");
for(int i = 0; i < 10; i++) {
System.out.println(REPORT ING " + ((i + 1) * 10) +"%");
}
System.out.println("FINISH REPORT ");
}
}
Threads Programming
public class TestThread {
public static void main(String[] args) {
TestThread t = new TestThread();
t.exampleWithoutThread();
}
private void exampleWithoutThread() {
Download d = new Download();
Upload u = new Upload();
Report r = new Report();
d.start();
u.start();
r.start();
System.out.println("DOING OTHER THINGS");
}
}
Threads Programming
public class TestThread {
public static void main(String[] args) {
TestThread t = new TestThread();
t.exampleWithThread();
}
private void exampleWithThread() {
Download d = new Download();
Upload u = new Upload();
Report r = new Report();
Thread a = new Thread(d, "D");
Thread b = new Thread(u, "U");
Thread c = new Thread(r, "R");
a.start(); b.start(); c.start();
System.out.println("DOING OTHER THINGS");
}
}
Threads Programming
public class Account {
private int balance = 50;
public void withdraw(int amount) {
balance = balance - amount;
}
public int getBalance() {
return balance;
}
}
Threads Advanced
public class AccountTest {
private Account account = new Account();
public void run() {
for(int i = 0; i < 5; i++) {
makeWithdrawal(10);
if (account.getBalance() < 0) System.out.println("INSUFFICIENT BALANCE");
}
}
private void makeWithdrawal(int amount) {
if(account.getBalance() >= amount) {
System.out.println(Thread.currentThread().getName() + " is withdrawing");
account.withdraw(amount);
System.out.println(Thread.currentThread().getName() + " complete withdrawing");
} else System.out.println(Thread.currentThread().getName() + " not enough: " + account.getBalance());
public static void main(String[] args) {
AccountDanger r = new AccountDanger();
Thread a = new Thread(r, "Fred"); Thread b = new Thread(r, "Lucy");
a.start(); b.start();
}
}
Threads Advanced
public class AccountTest {
private Account account = new Account();
public void run() {
for(int i = 0; i < 5; i++) {
makeWithdrawal(10);
if (account.getBalance() < 0) System.out.println("INSUFFICIENT BALANCE");
}
}
private synchronized void makeWithdrawal(int amount) {
if(account.getBalance() >= amount) {
System.out.println(Thread.currentThread().getName() + " is withdrawing");
account.withdraw(amount);
System.out.println(Thread.currentThread().getName() + " complete withdrawing");
} else System.out.println(Thread.currentThread().getName() + " not enough: " + account.getBalance());
public static void main(String[] args) {
AccountDanger r = new AccountDanger();
Thread a = new Thread(r, "Fred"); Thread b = new Thread(r, "Lucy");
a.start(); b.start();
}
}
Threads Advanced
public class Calculation implements Runnable {
int total;
public void run() {
synchronized (this) {
for(int i = 0; i < 100; i++) {
total += 1;
}
notifyAll();
}
}
}
Threads Advanced
public class TestCalculation {
public static void main(String[] args) {
Calculation c = new Calculation();
Thread a = new Thread(c);
a.start();
synchronized (a) {
try {
System.out.println(Waiting till finish");
a.wait();
} catch (Exception e) { }
System.out.println("TOTAL = " + t.total);
}
}
}
Parameters vs Arguments
Parameters:
public int calculateAge(Date date1, Date date2) {
int result;
// more logic
return result;
}
Arguments:
int age = calculateAge(birthDate, currentDate);
Generics - Basic
We want to have a parameter that represents a
type, not a value
We'll instantiate objects-of-the-generic-class
using different types (Integer, Timestamp,
Double, Thread) as the type argument
Each object will be specialized to do work on
that specific actual type argument
Generics - What Generic Solves
Reduce the amount of casting, particularly
when using the Java data structure classes
known as the collection classes
Up to JDK 1.4, collections held Objects.
Variables of any class type could be put into any
collection, because all class types are
compatible with the type used in a collection,
Object. When you retrieved something from a
collection, you had to figure out what type it
really was, then cast it back to that.
Generics - What Generic Solves
public static void main(String[] args) {
List nonGeneric = new ArrayList();
nonGeneric.add(new Student("1", "Hari"));
nonGeneric.add(new Student("2", Solihin"));
for(int i = 0; i < nonGeneric.size(); i++) {
Student s = (Student) nonGeneric.get(i);
System.out.println(s.getName());
}
}
Generics - What Generic Solves
public static void main(String[] args) {
List<Student> generic = new ArrayList<Student> ();
generic.add(new Student("1", "Hari"));
generic.add(new Student("2", Solihin"));
for(int i = 0; i < generic.size(); i++) {
Student s = generic.get(i);
System.out.println(s.getName());
}
}
Generics - What Generic Solves
The generic feature in Java lets you tell the compiler
about the type that you expect to load into a collection
class
You find out sooner (at compile-time, rather than run-
time) about any errors you have made involving the
types of objects you put into or take out of collections
Further, with generics, you catch all the errors. In the
bad old days, you only caught the errors you particularly
exercised
Generics - What Generic Solves
public static void main(String[] args) {
List nonGeneric = new ArrayList();
nonGeneric.add(new Student("1", "Hari"));
nonGeneric.add(new Student("2", Solihin"));
// No compile error, but will error in runtime
nonGeneric.add(Ardi");
for(int i = 0; i < nonGeneric.size(); i++) {
Student s = (Student) nonGeneric.get(i);
System.out.println(s.getName());
}
}
Generics - What Generic Solves
public static void main(String[] args) {
List<Student> generic = new ArrayList<Student>();
generic.add(new Student("1", "Hari"));
generic.add(new Student("2", Solihin"));
// Compile error, so wont be able to run
generic.add(Ardi");
for(int i = 0; i < generic.size(); i++) {
Student s = generic.get(i);
System.out.println(s.getName());
}
}
Generics - Code
public class Generic<T> {
public void getData(T data) {
System.out.println(Data = " + data.getClass());
}
public static void main(String[] args) {
Generic<Integer> t = new Generic<Integer>();
t.getData(new Integer(3));
}
}
Generics - Code
public class Generic<T> {
public void getData(T data) {
System.out.println(Data = " + data.getClass());
}
public static void main(String[] args) {
Generic<String> t = new Generic<String>();
t.getData();
}
}
Generics - Code
public class Generic<T> {
public void getData(T data) {
System.out.println(Data = " + data.getClass());
}
public static void main(String[] args) {
Generic<Student> t = new Generic<Student>();
t.getData();
}
}
Generics Class or Interface
public interface List<E>
boolean add(E o)
The <E> is a placeholder for the type you pass in
The E is only a convention. Any valid Java identifier
would work
Generics Class or Interface
List<Animal> list = new ArrayList<Animal>();
boolean add(Animal a);
E stands for "Element," and it's used when the template
is a collection
The other main convention is T (stands for "type"), used
for, well, things that are NOT collections
Java Code Convention
Classes and interfaces:
The first letter should be capitalized
If several words are linked together to form the name,
the first letter of the inner words should be uppercase
(a format that's sometimes called "camelCase")
For classes, the names should typically be nouns. For
example: Dog, Account, PrintWriter
For interfaces, the names should typically be
adjectives like: Runnable, Serializable
Java Code Convention
Methods:
The first letter should be lowercase, and then normal
camelCase rules should be used
In addition, the names should typically be verb-noun
pairs
For example:
getBalance
doCalculation
setCustomerName
Java Code Convention
Variables:
Like methods, the camelCase format should be used,
starting with a lowercase letter
Sun recommends short, meaningful names, which
sounds good to us
Some examples:
buttonWidth
accountBalance
myString
Java Code Convention
Constants:
Java constants are created by marking variables
static and final
They should be named using uppercase letters with
underscore characters as separators
For example: MIN_HEIGHT, PAGE_SIZE
Thank You