Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / November 2006

Tip: Looking for answers? Try searching our database.

Threads - synchronization

Thread view: 
jimmie0@wp.pl - 20 Nov 2006 11:09 GMT
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();

       }

}
Gordon Beaton - 20 Nov 2006 11:25 GMT
> 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

Signature

[ 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

jimmie0@wp.pl - 20 Nov 2006 12:28 GMT
Gordon Beaton napisal(a):
> > Hello, i'm writing java program using Threads, but i don't quite
> > understeand some...
[quoted text clipped - 7 lines]
> [ 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)
jimmie0@wp.pl - 20 Nov 2006 12:29 GMT
jimm...@wp.pl napisal(a):
> Gordon Beaton napisal(a):
> > > Hello, i'm writing java program using Threads, but i don't quite
[quoted text clipped - 18 lines]
>     at Th.ThC(Th.java:70)
>     at Th.run(Th.java:17)

and i changed recurency to while loop
Gordon Beaton - 20 Nov 2006 12:49 GMT
> 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

Signature

[ 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

jimmie0@wp.pl - 20 Nov 2006 14:32 GMT
Gordon Beaton napisal(a):
> > i use this because if i try to synchronize on class System.out
> > [synchronize(System.out) compilator display some errors (for example in
[quoted text clipped - 44 lines]
> [ 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();
    }
}
blmblm@myrealbox.com - 22 Nov 2006 09:54 GMT
> 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
> {
[quoted text clipped - 98 lines]
>     }
> }

Signature

B. L. Massingill
ObDisclaimer:  I don't speak for my employers; they return the favor.

Lew - 26 Nov 2006 23:47 GMT
Gordon Beaton napisal(a):
>> A correct solution should not require sleep() at all.

> 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.)


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.