Threads - synchronization

Discussion in 'Java' started by jimmie0@wp.pl, Nov 20, 2006.

  1. Guest

    Hello, i'm writing java program using Threads, but i don't quite
    understeand some...

    My program has 4 threads, each one prints on System.out one letter: A,
    B, C or D. There are some rules they must obey.
    in any moment number of letters
    1. A + B <= C + D
    2.A <= 2*B
    3. after C next letter C can be print after letter D

    using notify, notifyAll, wait

    there is my code, i synchronized methods but working program prints
    some strange results, maybe you can help me?

    Thanks for any help.

    there is my code:

    public class Th extends Thread
    {
    private int which;
    private static int[] howMany = {0, 0, 0, 0} ;

    public Th(int which)
    {
    this.which= which;
    }

    public void run()
    {
    switch (which)
    {
    case 1: ThA(); break;
    case 2: ThB(); break;
    case 3: ThC(); break;
    case 4: ThD(); break;
    }
    }

    public void ThA()
    {
    synchronized(this)
    {
    if ( (howMany[0]+howMany[1]) <
    (howMany[2]+howMany[3]) && (howMany[0] <= 2*howMany[1]))
    {
    System.out.println("A");
    howMany[0]++;
    }

    try {
    sleep(500);
    }catch(InterruptedException e) {}

    ThA();
    }
    }

    public void ThB()
    {
    synchronized(this)
    {
    if ( (howMany[0]+howMany[1]) <
    (howMany[2]+howMany[3]) )
    {
    System.out.print("B");
    howMany[1]++;
    }

    try {
    sleep(1110);
    }catch(InterruptedException e) {}

    ThB();
    }
    }

    public void ThC()
    {
    synchronized(this)
    {
    System.out.print("C");
    howMany[2]++;

    try {
    wait();
    sleep(100);
    }catch(InterruptedException e) {}
    }
    ThC();
    }

    public void ThD()
    {
    synchronized(this)
    {
    System.out.print("D");
    howMany[3]++;

    try {
    notify();
    sleep(1000);
    }catch(InterruptedException e) {}

    }
    ThD();
    }

    public static void main(String[] args)
    {


    new Th(1).start();
    new Th(2).start();
    new Th(3).start();
    new Th(4).start();


    }

    }
     
    , Nov 20, 2006
    #1
    1. Advertising

  2. On 20 Nov 2006 03:09:37 -0800, wrote:
    > Hello, i'm writing java program using Threads, but i don't quite
    > understeand some...


    Here's an important hint: what object does "this" refer to in each of
    the four threads?

    /gordon

    --
    [ don't email me support questions or followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Nov 20, 2006
    #2
    1. Advertising

  3. Guest

    Gordon Beaton napisal(a):
    > On 20 Nov 2006 03:09:37 -0800, wrote:
    > > Hello, i'm writing java program using Threads, but i don't quite
    > > understeand some...

    >
    > Here's an important hint: what object does "this" refer to in each of
    > the four threads?
    >
    > /gordon
    >
    > --
    > [ don't email me support questions or followups ]
    > g o r d o n + n e w s @ b a l d e r 1 3 . s e


    i use this because if i try to synchronize on class System.out
    [synchronize(System.out) compilator display some errors (for example in
    third method i synchronize System.out):

    CDjava.lang.IllegalMonitorStateException: current thread not owner
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Unknown Source)
    at Th.ThC(Th.java:70)
    at Th.run(Th.java:17)
     
    , Nov 20, 2006
    #3
  4. Guest

    napisal(a):
    > Gordon Beaton napisal(a):
    > > On 20 Nov 2006 03:09:37 -0800, wrote:
    > > > Hello, i'm writing java program using Threads, but i don't quite
    > > > understeand some...

    > >
    > > Here's an important hint: what object does "this" refer to in each of
    > > the four threads?
    > >
    > > /gordon
    > >
    > > --
    > > [ don't email me support questions or followups ]
    > > g o r d o n + n e w s @ b a l d e r 1 3 . s e

    >
    > i use this because if i try to synchronize on class System.out
    > [synchronize(System.out) compilator display some errors (for example in
    > third method i synchronize System.out):
    >
    > CDjava.lang.IllegalMonitorStateException: current thread not owner
    > at java.lang.Object.wait(Native Method)
    > at java.lang.Object.wait(Unknown Source)
    > at Th.ThC(Th.java:70)
    > at Th.run(Th.java:17)


    and i changed recurency to while loop
     
    , Nov 20, 2006
    #4
  5. On 20 Nov 2006 04:28:27 -0800, wrote:
    > i use this because if i try to synchronize on class System.out
    > [synchronize(System.out) compilator display some errors (for example in
    > third method i synchronize System.out):
    >
    > CDjava.lang.IllegalMonitorStateException: current thread not owner


    The problem is not that you chose System.out. The problem is that your
    use of wait() or notify() did not specify the same object!

    You get the error when you attempt to call wait() or notify() without
    specifing an object that you are currently synchronized on, e.g:

    synchronized (foo) {
    foo.wait();
    }

    Think of wait() and notify() as a *message* sent from one thread,
    through the synchronization object, to another. Obviously they need to
    synchronize on the *same* object, or the message will not arrive.

    When you call wait() or notify() without specifying an object, "this"
    is implied. The problem with "this" is that it refers to a *different*
    object in each of your threads, so there is no mutual synchronization.

    Note too that you should never use wait() or notify() without a
    corresponding condition (like the relationship you mentioned in your
    first post). Call notify() only after doing something that changes the
    condition, and call wait() in a loop, only after detecting that the
    condition has changed:

    synchronized (foo) {
    foo.do_something();
    foo.notify();
    }

    synchronized (foo) {
    while (!foo.some_condition()) {
    foo.wait();
    }
    }

    A correct solution should not require sleep() at all.

    /gordon

    --
    [ don't email me support questions or followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Nov 20, 2006
    #5
  6. Guest

    Gordon Beaton napisal(a):
    > On 20 Nov 2006 04:28:27 -0800, wrote:
    > > i use this because if i try to synchronize on class System.out
    > > [synchronize(System.out) compilator display some errors (for example in
    > > third method i synchronize System.out):
    > >
    > > CDjava.lang.IllegalMonitorStateException: current thread not owner

    >
    > The problem is not that you chose System.out. The problem is that your
    > use of wait() or notify() did not specify the same object!
    >
    > You get the error when you attempt to call wait() or notify() without
    > specifing an object that you are currently synchronized on, e.g:
    >
    > synchronized (foo) {
    > foo.wait();
    > }
    >
    > Think of wait() and notify() as a *message* sent from one thread,
    > through the synchronization object, to another. Obviously they need to
    > synchronize on the *same* object, or the message will not arrive.
    >
    > When you call wait() or notify() without specifying an object, "this"
    > is implied. The problem with "this" is that it refers to a *different*
    > object in each of your threads, so there is no mutual synchronization.
    >
    > Note too that you should never use wait() or notify() without a
    > corresponding condition (like the relationship you mentioned in your
    > first post). Call notify() only after doing something that changes the
    > condition, and call wait() in a loop, only after detecting that the
    > condition has changed:
    >
    > synchronized (foo) {
    > foo.do_something();
    > foo.notify();
    > }
    >
    > synchronized (foo) {
    > while (!foo.some_condition()) {
    > foo.wait();
    > }
    > }
    >
    > A correct solution should not require sleep() at all.
    >
    > /gordon
    >
    > --
    > [ don't email me support questions or followups ]
    > g o r d o n + n e w s @ b a l d e r 1 3 . s e


    i think that now is ok. can you take a look?


    public class Th extends Thread
    {
    private int which;
    private static int[] howMany = {0, 0, 0, 0} ;
    private static Object obj;

    public Th(int which)
    {
    this.which= which;
    }


    public void run()
    {
    switch (which)
    {
    case 1: ThA(); break;
    case 2: ThB(); break;
    case 3: ThC(); break;
    case 4: ThD(); break;
    }
    }

    public void ThA()
    {
    while(true)
    {
    synchronized(obj)
    {
    if ( (howMany[0]+howMany[1]) < (howMany[2]+howMany[3]) &&
    (howMany[0] <= 2*howMany[1]))
    {
    System.out.print("A");
    howMany[0]++;
    }

    try {
    sleep(100);
    }catch(InterruptedException e) {}
    }}
    }

    public void ThB()
    {
    while(true)
    {
    synchronized(obj)
    {
    if ( (howMany[0]+howMany[1]) < (howMany[2]+howMany[3]) )
    {
    System.out.print("B");
    howMany[1]++;
    }

    try {
    sleep(200);
    }catch(InterruptedException e) {}
    }}
    }

    public void ThC()
    {
    while(true)
    {
    synchronized(obj)
    {
    System.out.print("C");
    howMany[2]++;

    try {
    obj.wait();
    sleep(300);
    }catch(InterruptedException e) {}
    }
    }}


    public void ThD()
    {
    while(true)
    {
    synchronized(obj)
    {
    System.out.print("D");
    howMany[3]++;

    try {
    obj.notifyAll();
    sleep(1000);
    }catch(InterruptedException e) {}

    }}
    }

    public static void main(String[] args)
    {

    obj = new Object();
    new Th(1).start();
    new Th(2).start();
    new Th(3).start();
    new Th(4).start();
    }
    }
     
    , Nov 20, 2006
    #6
  7. Guest

    In article <>,
    <> wrote:
    > Gordon Beaton napisal(a):


    [ snip ]

    > > A correct solution should not require sleep() at all.


    [ snip ]

    > i think that now is ok. can you take a look?


    Well, I'm not Gordon, and I'm guessing that you're considering
    this problem solved and moving on to something else (in the
    thread with subject line "Threads interruption"), but .... :

    Is there a reason why you're using wait() and notifyAll() in ThC()
    and ThD() but not in ThA() and ThB()? and are the calls to sleep()
    meant to make thing synchronize right, or just to slow things down
    so you can observe a desired interaction?

    (I had some trouble understanding your original problem description,
    and maybe it explains the difference between the logic in ThA()/ThB()
    versus ThC()/ThD(). Apologies if that's the case.)

    > public class Th extends Thread
    > {
    > private int which;
    > private static int[] howMany = {0, 0, 0, 0} ;
    > private static Object obj;
    >
    > public Th(int which)
    > {
    > this.which= which;
    > }
    >
    >
    > public void run()
    > {
    > switch (which)
    > {
    > case 1: ThA(); break;
    > case 2: ThB(); break;
    > case 3: ThC(); break;
    > case 4: ThD(); break;
    > }
    > }
    >
    > public void ThA()
    > {
    > while(true)
    > {
    > synchronized(obj)
    > {
    > if ( (howMany[0]+howMany[1]) < (howMany[2]+howMany[3]) &&
    > (howMany[0] <= 2*howMany[1]))
    > {
    > System.out.print("A");
    > howMany[0]++;
    > }
    >
    > try {
    > sleep(100);
    > }catch(InterruptedException e) {}
    > }}
    > }
    >
    > public void ThB()
    > {
    > while(true)
    > {
    > synchronized(obj)
    > {
    > if ( (howMany[0]+howMany[1]) < (howMany[2]+howMany[3]) )
    > {
    > System.out.print("B");
    > howMany[1]++;
    > }
    >
    > try {
    > sleep(200);
    > }catch(InterruptedException e) {}
    > }}
    > }
    >
    > public void ThC()
    > {
    > while(true)
    > {
    > synchronized(obj)
    > {
    > System.out.print("C");
    > howMany[2]++;
    >
    > try {
    > obj.wait();
    > sleep(300);
    > }catch(InterruptedException e) {}
    > }
    > }}
    >
    >
    > public void ThD()
    > {
    > while(true)
    > {
    > synchronized(obj)
    > {
    > System.out.print("D");
    > howMany[3]++;
    >
    > try {
    > obj.notifyAll();
    > sleep(1000);
    > }catch(InterruptedException e) {}
    >
    > }}
    > }
    >
    > public static void main(String[] args)
    > {
    >
    > obj = new Object();
    > new Th(1).start();
    > new Th(2).start();
    > new Th(3).start();
    > new Th(4).start();
    > }
    > }
    >



    --
    B. L. Massingill
    ObDisclaimer: I don't speak for my employers; they return the favor.
     
    , Nov 22, 2006
    #7
  8. Lew Guest

    Gordon Beaton napisal(a):
    >> A correct solution should not require sleep() at all.


    wrote:
    > i think that now is ok. can you take a look?
    >
    >
    > public class Th extends Thread
    > {

    ....
    > sleep(100);

    ....
    > sleep(200);

    ....
    > sleep(300);

    ....
    > sleep(1000);

    ....
    > }


    (P.S., avoid embedding TAB characters in newsgroup posts.)
     
    Lew, Nov 26, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. yoda
    Replies:
    2
    Views:
    462
    =?utf-8?Q?Bj=C3=B6rn_Lindstr=C3=B6m?=
    Aug 1, 2005
  2. threads without threads

    , Aug 27, 2004, in forum: C Programming
    Replies:
    4
    Views:
    432
    William Ahern
    Aug 27, 2004
  3. Replies:
    4
    Views:
    381
    Daniel Pitts
    Feb 8, 2008
  4. Replies:
    21
    Views:
    737
    Lasse Reichstein Nielsen
    Jun 27, 2008
  5. Zd Yu
    Replies:
    7
    Views:
    126
    Zd Yu
    May 16, 2011
Loading...

Share This Page