Java Language and OOP Part VI By Hari Christian
Jan 15, 2015
Java Language and OOP Part VIBy 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 Solvespublic 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 Solvespublic 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 won’t 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 - Codepublic 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 - Codepublic 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 - Codepublic 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