This is some information on the Java 6 certification that I prepare. This information is not very well structured and it is most of the time an answer to the questions that come when I read the SCJP 6 book (Bates and Sierra). *** AS OF 5 OF MARCH 2010, I AM SCJP 6.0 ***

Saturday, January 30, 2010

28 - Review - xxxValue() - parseXxx() - valueOf() - Java 1.6.0_17

package chap3review;

public class Main {

    public static void main(String[] args) {
      
        // NOT STATIC
        //xxxValue()

        Byte aByte = 125;
        byte b = aByte.byteValue();
        short s = aByte.shortValue();
        int i = aByte.intValue();
        long l = aByte.longValue();
        float f = aByte.floatValue();
        double d =  aByte.doubleValue();

        Integer aInteger = 6753;
        i = aInteger.intValue();
        l = aInteger.longValue();
        f = aInteger.floatValue();
        d = aInteger.doubleValue();

        Boolean aBoolean = true;
        boolean bo = aBoolean.booleanValue();

        // Static
        // parseXxx

        b = Byte.parseByte("127"); // Exception in thread "main" java.lang.NumberFormatException: Value out of range. Value:"256" Radix:10
        // 8 bits signed -128..127 !!!
        i = Integer.parseInt("123456");
        bo = Boolean.parseBoolean("TRUE");
      
        //static 
        // valueOf()

        Byte anotherByte = Byte.valueOf("-128");
        anotherByte = Byte.valueOf(b); // NO BYTE LITTERALS !!!

        Integer  anotherInteger = Integer.valueOf("123456");
        anotherInteger = Integer.valueOf(123456);
    }
}

Friday, January 29, 2010

27 - Review - type of an array - level basic - Java 1.6.0_17 - NB 6.8

What is the output ?

package pkg1;

public class Class10 {

    static Integer[] arrayofINT = { 1, 2, 3, 4 ,5};

    public static void main(String[] args) {

        if(arrayofINT instanceof Object) {
            System.out.println("arrayofINT is an Object !");
        }
        if(arrayofINT instanceof Integer[]) {
            System.out.println("arrayofINT is an Integer[] !");
        }
    }
}

run:
arrayofINT is an Object !
arrayofINT is an Integer[] !
BUILD SUCCESSFUL (total time: 0 seconds)

26 - Review - protected - level basic - Java 1.6.0_17 - NB 6.8

??? protected ??? All the buzz about this keyword...

Let's try to do it simple...

http://en.wikibooks.org/wiki/Java_Programming/Keywords/protected

protected means default + inheritance

  • If you are in a separate pkg, you have access to the protected members ONLY if you extend the class where the protected member is defined.
  •  In the class that extends the class where the protected member is defined you have access to the member using DIRECTLY the member name (only if you didn't you the same name in the class and in this case the member protected is hidden) and using the keyword 'super'. 
  • If the protected member is hidden then use super. If you want to access a method protected in a subclass user the member name (or again if it is hidden then use super).
  • Don't try to user super.super (or super.super.super). It is not implemented... If you want a member to be accessed from all the inheritance tree then make the name unique or (it is a possibility) make a kind of proxy member that will have to call super from the parent class (I don't like this).
example :






/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkg3.pkg31;

/**
 *
 * @author Rudy
 */
public class Class1 {

    private int a;
    private int b;

    protected int c = -1;

    protected int d = -888;

    protected Class1(int a, int b) {
        System.out.println("Class1-protected Class1(int a, int b)");
        this.a = a;
        this.b = b;
    }

    protected int calculation() {
        System.out.println("Class1-protected int calculation()");
        return a + b;
    }


    protected void simplyToAnnoyYou() {
        System.out.println("simplyToAnnoyYou");
    }




    public static void main(String[] args) {
        System.out.println("main from pkg31.Class1\n");

        System.out.println(new Class1(1, 2).calculation());
    }
}

run:
main from pkg31.Class1

Class1-protected Class1(int a, int b)
Class1-protected int calculation()
3
BUILD SUCCESSFUL (total time: 0 seconds)

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkg3.pkg32;

/**
 *
 * @author Rudy
 */
public class Class2 extends pkg3.pkg31.Class1 {

    Class2(int a, int b) {
        super(a, b);
        System.out.println("Class2(int a, int b)");
        super.c = -2;
    }

    @Override
    protected int calculation() {
        System.out.println("Class2-protected int calculation()");
        return super.calculation();
    }

    protected int calculation1() {
        System.out.println("Class2-protected int calculation1()");
        int a = super.calculation() + super.c + c;
        return a;
    }

    public static void main(String[] args) {
        System.out.println("main from pkg32.Class2\n");

        Class2 class2 = new Class2(1, 3);

        System.out.println("class2.calculation :  " + class2.calculation());

        System.out.println("c from class1 (protected) in class 2: " + class2.c);

        System.out.println("calculation1 : " + class2.calculation1());
    }
}

run:
main from pkg32.Class2

Class1-protected Class1(int a, int b)
Class2(int a, int b)
Class2-protected int calculation()
Class1-protected int calculation()
class2.calculation :  4
c from class1 (protected) in class 2: -2
Class2-protected int calculation1()
Class1-protected int calculation()
calculation1 : 0
BUILD SUCCESSFUL (total time: 0 seconds)






/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkg3.pkg32;

/**
 *
 * @author Rudy
 */
public class Class3 extends Class2 {

    int d = -999;

    Class3(int a, int b) {
        super(a, b);
        System.out.println("Class3(int a, int b)");
        super.c = -4;
    }

    @Override
    protected int calculation() {
        System.out.println("Class3.calculation()");
        return super.calculation();
    }

    @Override
    protected int calculation1() {
        System.out.println("Class3.calculation1()");
        int a = super.calculation() + super.c + c;
        return a;
    }

    int getD() {
        return super.d;
    }

    public static void main(String[] args) {
        System.out.println("main from pkg32.Class2\n");

        Class3 class3 = new Class3(1, 3);

        System.out.println("class3.calculation :  " + class3.calculation());

        System.out.println("c from class1 (protected) in class 2: " + class3.c);

        System.out.println("calculation1 : " + class3.calculation1());

        System.out.println("d : " + class3.d);
        
        System.out.println("d from class1 and not defined in class 2 but hidden in class3 : " + class3.getD());

        class3.simplyToAnnoyYou();
    }
}

run:
main from pkg32.Class2

Class1-protected Class1(int a, int b)
Class2(int a, int b)
Class3(int a, int b)
Class3.calculation()
Class2-protected int calculation()
Class1-protected int calculation()
class3.calculation :  4
c from class1 (protected) in class 2: -4
Class3.calculation1()
Class2-protected int calculation()
Class1-protected int calculation()
calculation1 : -4
d : -999
d from class1 and not defined in class 2 but hidden in class3 : -888
simplyToAnnoyYou
BUILD SUCCESSFUL (total time: 0 seconds)

Can you explain all the output ?
:-)



Thursday, January 28, 2010

25 - Review - private - level basic - Java 1.6.0_17 - NB 6.8

I wanted to make you aware (if you are not) of the following...

If you make your constructor "private" you can't invoke the constructor from another class... But you can still invoke it from the SAME class. In Netbeans we are used that Netbeans will generate automatically a Main class and a pvsm (public static void main[] args) method in the main class. In this case if you try to instantiate a class using a private constructor you cant... You have to give another ways (have a look to singletons). But if you put a pvsm in the class were the private constructor is defined, no problem you can instantiate the class.

package pkg3.pkg31;



class Class1 {


    protected int a;
    protected int b;


    private Class1(int a, int b) {
        this.a = a;
        this.b = b;
    }


    protected int calculation() {
        return a + b;
    }


    public static void main(String[] args) {
        System.out.println(new Class1(1, 2).calculation());
    }
}

run:
3
BUILD SUCCESSFUL (total time: 0 seconds)

Tuesday, January 26, 2010

24 - Thread : notify/notifyall- level basic - Java 1.6.0_17 - NB 6.8

(
after all the Master Exam questions, they ask you several times to choose notify or notifyAll ...
most of the time if you answer (please read the question carefully) notifyAll, it is the wrong answer...
why ? it is because there is a producer and several consumers... after the producer produced something the producer will notify the consumers... the way they wrote the example, they do a wait but as soon as the thread is notified they do not check that something was produced (in the consumer thread)
if the producer do notifyAll, then (and it is not new) only 1 thread continues in the synchronized block...
this thread will consume what was produced and exit the synch block and it is fine...
but if notifyAll was used by the producer, then the second, third,... thread (one of those) are now notified but... nothing was produced and a thread will...consume (without checking that something was produced) and...that can cause a IndexOutOfBoundsException to be thrown if the thread calls (by ex) refArrayList.remove(0) without checking that the ArrayList is empty... If you answer notify, then only one thread will be notified and then consume... Then the producer after a while (sometimes they put a sleep) will produce and then call notify...
imho you serialize the way you produce and consume


you produce
then notify1 amongst all the threads
...

or
you produce
then notifyAll

all the threads will be able to continue before the producer produced (one by one in the synch blcok)
and that can cause a problem
(I repeat you have to find a way that the producer made something new)

*** Hope this help ***

)



3 classes. A Main that will start the threads. A producer (calling notify/notifyall) and  consumers.

The Producer

package threadnotifyall;

public class Calculator extends Thread {

    int total;

    public void run() {
        try {
            System.out.println("Calculator...");
            Thread.currentThread().sleep(1000);
            synchronized (this) {
                for (int i = 0; i < 100; i++) {
                    total += i;
                }
                Thread.currentThread().sleep(5000);
                notifyAll(); // OR
                //notify();
            }
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
    }
}

The Consumer

package threadnotifyall;

public class Reader extends Thread {
    Calculator c; // reference to the producer

    public Reader(Calculator c) {
        this.c = c;
    }

    public void run() { // it is a thread 
        synchronized(c) { // lock the producer (try to lock)
            try {
                System.out.println(Thread.currentThread().getName() + " waiting for calculation...");
                c.wait(); // if the producer is locked but did not notify (us) wait to be notified (1 and only 1 thread !) or wait forever (see my remarks later)
            } catch(InterruptedException ie) {
                ie.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()  + " Total is :" + c.total); // show the thread that was notified
        }
    }
}

The bandmaster

package threadnotifyall;

public class Main {

    public static void main(String[] args) {
      
        Calculator calculator = new Calculator(); // the producer

        new Reader(calculator).start(); // 3 consumers threads (we pass the producer they have to wait for)
        new Reader(calculator).start();
        new Reader(calculator).start();
        calculator.start(); // the 3 consumers were started (all waiting and the producer shows up)
        System.out.println("end of main"); // end of the THREAD main (because main is a THREAD)
    }
}

With notify

IT IS AN ASSUMPTION BECAUSE THE WAY THE JAVA SCHEDULER WILL CHOOSE THE THREAD DEPENDS ON A FEW FACTORS (WE CAN INFLUENCE)

run:
Thread-1 waiting for calculation...
Thread-2 waiting for calculation...
Thread-3 waiting for calculation...
end of main
Calculator...
Thread-1 Total is :4950
Thread-3 Total is :4950
Thread-2 Total is :4950
BUILD SUCCESSFUL (total time: 5 seconds)

run:
Thread-1 waiting for calculation...
Thread-2 waiting for calculation...
end of main
Thread-3 waiting for calculation...
Calculator...
Thread-1 Total is :4950
Thread-3 Total is :4950
Thread-2 Total is :4950
BUILD SUCCESSFUL (total time: 5 seconds)

I did several executions and can report that if we use notify, it is always the first thread that was started that will be choosen (notified that the producer has something to deliver). In the output as it is Thread-1 that was the first to be started (and waiting), Thread-1 is the first to be notified... You can see that the main thread terminated BEFORE the 3 threads were terminated. But Java is polite :-) and will wait that the 3 consumers threads will terminate.

With notifyall

run:
Thread-1 waiting for calculation...
Thread-2 waiting for calculation...
end of main
Thread-3 waiting for calculation...
Calculator...
Thread-3 Total is :4950
Thread-2 Total is :4950
Thread-1 Total is :4950
BUILD SUCCESSFUL (total time: 5 seconds)

run:
Thread-1 waiting for calculation...
Thread-3 waiting for calculation...
Thread-2 waiting for calculation...
end of main
Calculator...
Thread-2 Total is :4950
Thread-3 Total is :4950
Thread-1 Total is :4950
BUILD SUCCESSFUL (total time: 5 seconds)

run:
Thread-1 waiting for calculation...
Thread-3 waiting for calculation...
Thread-2 waiting for calculation...
end of main
Calculator...
Thread-2 Total is :4950
Thread-3 Total is :4950
Thread-1 Total is :4950
BUILD SUCCESSFUL (total time: 5 seconds)

As you can see using notifyall, it is the last thread that was started that was notified this time.

Following my experimentation with the kind of JVM that I use
  • If notify is used, then it is the thread that was the FIRST to be waiting that will be notified. Then the second,... Then the third... until all the threads waiting to be notified.
  • If notifyall is used, then it is the thread that was the LAST to be waiting that will be notified, then the previous, etc.
  • The Java scheduler will choose a thread to be notified (there is a list of threads awaiting) and the one that is awaken continues JUST AFTER the wait !!! But the awaken thread does not have to execute "synchronized" to get the lock. The Java scheduler guaranty the thread to receive the lock if the thread is chosen. ALL the other threads ARE WAITING to be notified (IMHO there are NOT in the runnable queue; the threads are in a special queue). They will all be notified ONE BY ONE. The way there are chosen depends on notify / notifyall. But the mechanism to awake the threads is the same. One by one !!! But look in the beg of this post, if nothing was produced and the thread that is awaken does not check that something is produced (with notifyAll) you can cause a IndexOutOfBoundsException to be thrown !!!
  • If you inverse the consumers and the producers meaning you start the producer first and later the consumer and let's say you also put a sleep just after the producer finishes. The consumers will ALL wait to be notified but will never be notified because the producer finished before any consumers were started. You see that the main thread is finished, but all the others keep waiting FOREVER !!! Thus the sequence of events is important and it is written  in the Sierra/Bates book that you have to wait for something that will happen (by example there is something to be read  from a queue and it is your application queue) but NOT unconditionaly !!!


Monday, January 25, 2010

23 - Thread : deadlock - level basic - Java 1.6.0_17 - NB 6.8

A deadlock is rather easy to produce having 2 actors (2 threads) accessing 2 resources at the same time but in different order !

T1-------------T2
res A----------res B
res B----------res A

If T1 put a lock on res A, T2 put a lock on res B, then T1 tries to lock res B (waiting the lock on res B to be released) an then T2 tries to lock res A (waiting the lock put by T1 to be released). The 2 threads do not speak to each others and will wait...indefinitely... The JVM seems not able to deal with such a problem...
You have to deal with it !!!


package threaddeadlock;

public class Main implements Runnable {

    ClassA refA = new ClassA();
    ClassB refB = new ClassB();

    void operation1() throws Exception {
        synchronized (refA) {
            refA.method1();
            synchronized (refB) {
                refB.method2();
            }
        }
    }

    void operation2() throws Exception {
        synchronized (refB) {
            refB.method2();
            synchronized (refA) {
                refA.method1();
            }
        }
    }

    public void run() {
        try {
            if (Thread.currentThread().getName().equals("t1")) {
                operation1();
            } else if (Thread.currentThread().getName().equals("t2")) {
                operation2();
            } else { // should be an assertion !!!
                System.err.println("thread name must be t1 or t2 !!!");
                System.exit(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Main main = new Main();
        Thread t1 = new Thread(main);
        t1.setName("t1");
        Thread t2 = new Thread(main);
        t2.setName("t2");
        t1.start();
        t2.start();
    }
}

wait forever in front of your screen... :-)


run:
t1 method1
t2 method2
BUILD STOPPED (total time: 13 minutes 30 seconds)



package threaddeadlock;

public class ClassA {

     void method1() {
        System.out.println(Thread.currentThread().getName() + " method1");
    }

}

package threaddeadlock;

public class ClassB {

     void method2() {
        System.out.println(Thread.currentThread().getName() + " method2");
    }
}



22 - Thread : same or different object ? - level basic - Java 1.6.0_17 - NB 6.8

Look at the 2 versions of main
1 will create a new object of type ClassA for every thread
the second will not and look at the difference !


package threadsleep;

public class Main {

    public static void main(String[] args) {
        // 1st version new object ClassA of every thread
        //ClassA ca = new ClassA();
        //Thread thread;
        for(int i=0; i < 10; i++) {
            //thread = new Thread(ca);
            //thread.start();
            new Thread(new ClassA()).start();
        }
    }
}

run:
Thread-0
a : Thread-0 sleeping 5 seconds...
Thread-1
a : Thread-1 sleeping 5 seconds...
Thread-3
a : Thread-3 sleeping 5 seconds...
Thread-5
a : Thread-5 sleeping 5 seconds...
Thread-7
a : Thread-7 sleeping 5 seconds...
Thread-6
a : Thread-6 sleeping 5 seconds...
Thread-2
a : Thread-2 sleeping 5 seconds...
Thread-4
a : Thread-4 sleeping 5 seconds...
Thread-8
a : Thread-8 sleeping 5 seconds...
Thread-9
a : Thread-9 sleeping 5 seconds...
a : Thread-0-Thread-0 after sleeping 5 seconds...
a : Thread-1-Thread-1 after sleeping 5 seconds...
a : Thread-5-Thread-5 after sleeping 5 seconds...
a : Thread-3-Thread-3 after sleeping 5 seconds...
a : Thread-7-Thread-7 after sleeping 5 seconds...
a : Thread-6-Thread-6 after sleeping 5 seconds...
a : Thread-2-Thread-2 after sleeping 5 seconds...
a : Thread-4-Thread-4 after sleeping 5 seconds...
a : Thread-9-Thread-9 after sleeping 5 seconds...
a : Thread-8-Thread-8 after sleeping 5 seconds...
BUILD SUCCESSFUL (total time: 10 seconds)

The instance variable "a" was not modified because for every thread there is a different "a" !

public class Main {

    public static void main(String[] args) {
        // 2nd version the thread will share the same object
        ClassA ca = new ClassA();
        Thread thread;
        for(int i=0; i < 10; i++) {
            thread = new Thread(ca);
            thread.start();
            //new Thread(new ClassA()).start();
        }
    }
}

run:
Thread-0
a : Thread-0 sleeping 5 seconds...
Thread-1
a : Thread-1 sleeping 5 seconds...
Thread-2
a : Thread-2 sleeping 5 seconds...
Thread-3
a : Thread-3 sleeping 5 seconds...
Thread-5
a : Thread-5 sleeping 5 seconds...
Thread-7
a : Thread-7 sleeping 5 seconds...
Thread-9
a : Thread-9 sleeping 5 seconds...
Thread-4
a : Thread-4 sleeping 5 seconds...
Thread-6
a : Thread-6 sleeping 5 seconds...
Thread-8
a : Thread-8 sleeping 5 seconds...
a : Thread-8-Thread-0 after sleeping 5 seconds...
a : Thread-8-Thread-1 after sleeping 5 seconds...
a : Thread-8-Thread-2 after sleeping 5 seconds...
a : Thread-8-Thread-5 after sleeping 5 seconds...
a : Thread-8-Thread-3 after sleeping 5 seconds...
a : Thread-8-Thread-7 after sleeping 5 seconds...
a : Thread-8-Thread-9 after sleeping 5 seconds...
a : Thread-8-Thread-4 after sleeping 5 seconds...
a : Thread-8-Thread-6 after sleeping 5 seconds...
a : Thread-8-Thread-8 after sleeping 5 seconds...
BUILD SUCCESSFUL (total time: 11 seconds)

The thread "8" had a big influence on all the others threads because the thread "8" modified the instance variable "a" ! In fact it is because this poor thread "8" was the last to be started and as he is the last, he modified the same "a" instance variable for all the threads !!!

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package threadsleep;

public class ClassA implements Runnable {

    String a;

    public void run() {
        Thread currenthread = Thread.currentThread();
        a = currenthread.getName();
        System.out.println(a);
        try {
            System.out.println("a : " + a + " sleeping 5 seconds...");
            currenthread.sleep(10000);
            System.out.println("a : " + a + "-" + currenthread.getName()+ " after sleeping 5 seconds...");
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
    }
}

You can share the same objects. You will avoid to waste memory... But if your threads modify the data... You have to find a way keep the operations/data modifications consistent... In other words all the operations you do that can corrupt the data have to be atomic to avoid the corruption...


- Rudy -


Followers