views:

85

answers:

2

Hi,

I am trying to get familiar with Java threads for the SCJP and I had a question.

In the below-written code i simply created: two Runnables with a common data storage (an array) and a synchronized write() method to fill it with data successively leaving a letter as a mark for each Runnable (A and B) in sequence.

I know the code is rough and could be better written but I was seeking the moral of the threads.

So now when I run it, it never terminates and the results stop at:

Still good. A0.

But when I change wait() to wait(100) it works just fine counting from 0 to 9 and it terminates normally. Could someone explain the reason behind that for me please?

Thank you.

public class ArrayThreads {

Object[] array = new Object[10];
boolean isA = true;

    int position = 0;

    int getIndex(){
        return position;
    }



class ThreadA implements Runnable{

            synchronized void write(String value){
                    while(!isA){
            try {
                wait();
            } catch (InterruptedException ex) {
                System.out.println("An error in" + value);
                ex.printStackTrace();
            }
        }
        array[position] = value + position;
        System.out.println(array[position]);
        position++;
        isA = !isA;
        notify();
    }

    public void run() {
        while(getIndex()<array.length){
            if (getIndex()==9) return;
            else
        write("A");}
    }
}

    class ThreadB implements Runnable{

                synchronized void write(String value){
                    while(isA){
            try {
                wait();
            } catch (InterruptedException ex) {
                System.out.println("An error in" + value);
                ex.printStackTrace();
            }
        }
        array[position] = value + position;
        System.out.println(array[position]);
        position++;
        isA = !isA;
        notify();
    }

    public void run() {
        while(getIndex()<array.length){
            if (getIndex()==9) return;
            else
        write("B");}
    }
}

    public static void main(String[] args){
        ArrayThreads threads = new ArrayThreads();
        Thread threadA = new Thread(threads.new ThreadA());
        Thread threadB = new Thread(threads.new ThreadB());
        System.out.println("Still good");

        threadB.start();
        threadA.start();
    }

}

+5  A: 

Your threads are each waiting and notifying separate objects - so they're not communicating with each other at all. If you want them to effectively release each other, they'll need a shared monitor to synchronize, wait on and notify.

It's "working" when you specify a timeout because it's effectively turning the wait call into a sleep call... still nothing is really waiting/notifying usefully, because the two threads are still dealing with separate monitors.

Jon Skeet
A: 

your objects are not working in same monitor.

you need to either move the wait() and notify() to same object like: http://www.java-samples.com/showtutorial.php?tutorialid=306

or you can notify the target object: http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ315_016.htm

when you set wait(100). you are setting a timeout. and definitely it will wake up after 100ms.

mohammad shamsi