synchronize seems not work

Discussion in 'Java' started by lonelyplanet999, Nov 13, 2003.

  1. Hi,

    I have 2 java programs doing similar things:
    ==============================================================================
    Program 1 below successfully achieved synchronization among 3 created
    threads such that the first printed 100 'A' before the second printed
    100 'B' followed by the third printed 100 'C'
    ==============================================================================
    class InSync extends Thread {

    StringBuffer letter;

    public InSync(StringBuffer letter) {
    this.letter = letter;
    }

    public void run() {
    synchronized(letter) {
    for (int i=1; i<=100; i++) {
    System.out.print(letter);
    }
    System.out.println();
    char temp = letter.charAt(0);
    ++temp;
    letter.setCharAt(0,temp);
    }
    }

    public static void main (String [] args) {
    StringBuffer sb = new StringBuffer("A");
    new InSync(sb).start();
    new InSync(sb).start();
    new InSync(sb).start();
    }

    }

    ==============================================================================
    Program 2 below aims to achieve the same function. However, the output
    was not expected.

    This program outputted below when ran.

    Thread-1
    AAAAAAAAAThread-3
    AAAThread-2
    AAAAAAAAAAA...... (80 'A's in one row)
    AAAAAAAAAAA...... (80 'A's in one row)
    AAAAAAAAAAA...... (80 'A's in one row)
    AAAAAA..... (38 'A's in one row)
    AACheck c=A
    AAAA.... (17 'A's in one row)
    ACheck c=A

    Check c=A

    Obviously, the code couldn't synchronize execution of the three
    threads. I couldn't understand what's the difference between program 1
    & 2 that caused failure of program 2 to outputted what's outputted by
    program 1 ?

    Tks ;\
    ==============================================================================
    class Ch9ex2 extends Thread {

    private StringBuffer sb = new StringBuffer("A");

    public static void main (String [] args) {
    Ch9ex2 mt1 = new Ch9ex2();
    Ch9ex2 mt2 = new Ch9ex2();
    Ch9ex2 mt3 = new Ch9ex2();
    mt1.start();
    mt2.start();
    mt3.start();
    }

    public void run() {
    System.out.println(Thread.currentThread().getName());
    synchronized(sb) {
    for (int i=0; i<100; i++) {
    System.out.print(sb);
    }
    System.out.println("");
    char c = sb.charAt(0);
    System.out.println("Check c="+c);
    c += 1;
    sb.setCharAt(0,c);
    }
    }

    }
    lonelyplanet999, Nov 13, 2003
    #1
    1. Advertising

  2. lonelyplanet999 wrote:
    > Obviously, the code couldn't synchronize execution of the three
    > threads. I couldn't understand what's the difference between program 1
    > & 2 that caused failure of program 2 to outputted what's outputted by
    > program 1 ?


    Java synchronization works with "monitors". Only one thread at a time can
    "own" a particular monitor and execute code that synchronizes on that monitor.
    Now the important thing is that each *Object* has its own monitor.

    In Program 1, all threads are given (in the constructor) an object to
    synchronize on, and it works because in the main method they are given
    the same object. In Program 2, each thread has a separate object that
    it synchronizes on, and thus effective no synchronization happens.
    Michael Borgwardt, Nov 13, 2003
    #2
    1. Advertising

  3. On 13 Nov 2003 08:17:28 -0800, lonelyplanet999 wrote:
    > Obviously, the code couldn't synchronize execution of the three
    > threads. I couldn't understand what's the difference between program 1
    > & 2 that caused failure of program 2 to outputted what's outputted by
    > program 1 ?


    Synchronization is based on obtaining a monitor that is part of the
    object you synchronize on. It is through the monitor that the threads
    communicate their intention to execute the critical section of code,
    and indicate when the code is busy.

    Your threads must synchronize on the *same* object, or they will not
    be synchronized with each other. It is possible to use different
    synchronization objects independently of one another.

    In your second example, you create a unique synchronization object in
    each thread:

    > private StringBuffer sb = new StringBuffer("A");


    ....preventing them from synchronizing with each other.

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
    Gordon Beaton, Nov 13, 2003
    #3
  4. Michael Borgwardt <> wrote in message news:<bp0blj$1jibq1$-berlin.de>...
    > lonelyplanet999 wrote:
    > > Obviously, the code couldn't synchronize execution of the three
    > > threads. I couldn't understand what's the difference between program 1
    > > & 2 that caused failure of program 2 to outputted what's outputted by
    > > program 1 ?

    >
    > Java synchronization works with "monitors". Only one thread at a time can
    > "own" a particular monitor and execute code that synchronizes on that monitor.
    > Now the important thing is that each *Object* has its own monitor.
    >
    > In Program 1, all threads are given (in the constructor) an object to
    > synchronize on, and it works because in the main method they are given
    > the same object. In Program 2, each thread has a separate object that
    > it synchronizes on, and thus effective no synchronization happens.


    Tks :)
    lonelyplanet999, Nov 15, 2003
    #4
  5. Gordon Beaton <> wrote in message news:<3fb3b2de$>...
    > On 13 Nov 2003 08:17:28 -0800, lonelyplanet999 wrote:
    > > Obviously, the code couldn't synchronize execution of the three
    > > threads. I couldn't understand what's the difference between program 1
    > > & 2 that caused failure of program 2 to outputted what's outputted by
    > > program 1 ?

    >
    > Synchronization is based on obtaining a monitor that is part of the
    > object you synchronize on. It is through the monitor that the threads
    > communicate their intention to execute the critical section of code,
    > and indicate when the code is busy.
    >
    > Your threads must synchronize on the *same* object, or they will not
    > be synchronized with each other. It is possible to use different
    > synchronization objects independently of one another.
    >
    > In your second example, you create a unique synchronization object in
    > each thread:
    >
    > > private StringBuffer sb = new StringBuffer("A");

    >
    > ...preventing them from synchronizing with each other.
    >
    > /gordon


    Tks :)
    lonelyplanet999, Nov 15, 2003
    #5
  6. lonelyplanet999

    Tony Dahlman Guest

    lonelyplanet999 wrote:
    >
    > Hi,
    >
    > I have 2 java programs doing similar things:
    > ==============================================================================
    > Program 1 below successfully achieved synchronization among 3 created
    > threads such that the first printed 100 'A' before the second printed
    > 100 'B' followed by the third printed 100 'C'
    > ==============================================================================
    > class InSync extends Thread {
    >
    > StringBuffer letter;
    >
    > public InSync(StringBuffer letter) {
    > this.letter = letter;
    > }
    >
    > public void run() {
    > synchronized(letter) {
    > for (int i=1; i<=100; i++) {
    > System.out.print(letter);
    > }
    > System.out.println();
    > char temp = letter.charAt(0);
    > ++temp;
    > letter.setCharAt(0,temp);
    > }
    > }
    >
    > public static void main (String [] args) {
    > StringBuffer sb = new StringBuffer("A");
    > new InSync(sb).start();
    > new InSync(sb).start();
    > new InSync(sb).start();
    > }
    >
    > }
    >
    > ==============================================================================
    > Program 2 below aims to achieve the same function. However, the output
    > was not expected.
    >
    > This program outputted below when ran.
    >
    > Thread-1
    > AAAAAAAAAThread-3
    > AAAThread-2
    > AAAAAAAAAAA...... (80 'A's in one row)
    > AAAAAAAAAAA...... (80 'A's in one row)
    > AAAAAAAAAAA...... (80 'A's in one row)
    > AAAAAA..... (38 'A's in one row)
    > AACheck c=A
    > AAAA.... (17 'A's in one row)
    > ACheck c=A
    >
    > Check c=A
    >
    > Obviously, the code couldn't synchronize execution of the three
    > threads. I couldn't understand what's the difference between program 1
    > & 2 that caused failure of program 2 to outputted what's outputted by
    > program 1 ?
    >
    > Tks ;\
    > ==============================================================================
    > class Ch9ex2 extends Thread {
    >
    > private StringBuffer sb = new StringBuffer("A");
    >
    > public static void main (String [] args) {
    > Ch9ex2 mt1 = new Ch9ex2();
    > Ch9ex2 mt2 = new Ch9ex2();
    > Ch9ex2 mt3 = new Ch9ex2();
    > mt1.start();
    > mt2.start();
    > mt3.start();
    > }
    >
    > public void run() {
    > System.out.println(Thread.currentThread().getName());
    > synchronized(sb) {
    > for (int i=0; i<100; i++) {
    > System.out.print(sb);
    > }
    > System.out.println("");
    > char c = sb.charAt(0);
    > System.out.println("Check c="+c);
    > c += 1;
    > sb.setCharAt(0,c);
    > }
    > }
    >
    > }


    No, synchronization is working just as it should. The real difference
    between the two classes is in you main() method.

    In the first case, you initialize the StringBuffer with 'A', then
    instantiate the first thread which increments to 'B' before releasing
    the lock. Thus the second thread sees a StringBuffer with 'B', etc.

    In the second case, you initialize all three threads with a StringBuffer
    with 'A', long before you start() them. The three threads are running
    in the appropriate order, just as you coded it.

    The code in the second version that prints "Check c=" is outside the
    synchronized block, so it competes for an opportunity to run and each
    thread may run it before or after the others.

    Does that answer your question?
    Regards, Tony Dahlman
    ---------------------------------------
    a(nospace)dahlman(at)attglobal(dot)net
    Tony Dahlman, Nov 16, 2003
    #6
  7. Tony Dahlman <> wrote in message news:<>...
    > lonelyplanet999 wrote:
    > >
    > > Hi,
    > >
    > > I have 2 java programs doing similar things:
    > > ==============================================================================
    > > Program 1 below successfully achieved synchronization among 3 created
    > > threads such that the first printed 100 'A' before the second printed
    > > 100 'B' followed by the third printed 100 'C'
    > > ==============================================================================
    > > class InSync extends Thread {
    > >
    > > StringBuffer letter;
    > >
    > > public InSync(StringBuffer letter) {
    > > this.letter = letter;
    > > }
    > >
    > > public void run() {
    > > synchronized(letter) {
    > > for (int i=1; i<=100; i++) {
    > > System.out.print(letter);
    > > }
    > > System.out.println();
    > > char temp = letter.charAt(0);
    > > ++temp;
    > > letter.setCharAt(0,temp);
    > > }
    > > }
    > >
    > > public static void main (String [] args) {
    > > StringBuffer sb = new StringBuffer("A");
    > > new InSync(sb).start();
    > > new InSync(sb).start();
    > > new InSync(sb).start();
    > > }

    >
    > > }
    > >
    > > ==============================================================================
    > > Program 2 below aims to achieve the same function. However, the output
    > > was not expected.
    > >
    > > This program outputted below when ran.
    > >
    > > Thread-1
    > > AAAAAAAAAThread-3
    > > AAAThread-2
    > > AAAAAAAAAAA...... (80 'A's in one row)
    > > AAAAAAAAAAA...... (80 'A's in one row)
    > > AAAAAAAAAAA...... (80 'A's in one row)
    > > AAAAAA..... (38 'A's in one row)
    > > AACheck c=A
    > > AAAA.... (17 'A's in one row)
    > > ACheck c=A
    > >
    > > Check c=A
    > >
    > > Obviously, the code couldn't synchronize execution of the three
    > > threads. I couldn't understand what's the difference between program 1
    > > & 2 that caused failure of program 2 to outputted what's outputted by
    > > program 1 ?
    > >
    > > Tks ;\
    > > ==============================================================================
    > > class Ch9ex2 extends Thread {
    > >
    > > private StringBuffer sb = new StringBuffer("A");
    > >
    > > public static void main (String [] args) {
    > > Ch9ex2 mt1 = new Ch9ex2();
    > > Ch9ex2 mt2 = new Ch9ex2();
    > > Ch9ex2 mt3 = new Ch9ex2();
    > > mt1.start();
    > > mt2.start();
    > > mt3.start();
    > > }
    > >
    > > public void run() {
    > > System.out.println(Thread.currentThread().getName());
    > > synchronized(sb) {
    > > for (int i=0; i<100; i++) {
    > > System.out.print(sb);
    > > }
    > > System.out.println("");
    > > char c = sb.charAt(0);
    > > System.out.println("Check c="+c);
    > > c += 1;
    > > sb.setCharAt(0,c);
    > > }
    > > }

    >
    > > }

    >
    > No, synchronization is working just as it should. The real difference
    > between the two classes is in you main() method.
    >
    > In the first case, you initialize the StringBuffer with 'A', then
    > instantiate the first thread which increments to 'B' before releasing
    > the lock. Thus the second thread sees a StringBuffer with 'B', etc.
    >
    > In the second case, you initialize all three threads with a StringBuffer
    > with 'A', long before you start() them. The three threads are running
    > in the appropriate order, just as you coded it.
    >
    > The code in the second version that prints "Check c=" is outside the
    > synchronized block, so it competes for an opportunity to run and each
    > thread may run it before or after the others.
    >
    > Does that answer your question?


    Tks :)

    > Regards, Tony Dahlman
    > ---------------------------------------
    > a(nospace)dahlman(at)attglobal(dot)net
    lonelyplanet999, Nov 16, 2003
    #7
    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. Frederic Gignac

    Expiration date seems not to work

    Frederic Gignac, Jul 4, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    406
    Frederic Gignac
    Jul 8, 2003
  2. Wootaek Choi
    Replies:
    1
    Views:
    288
    Marshal Antony
    Feb 10, 2004
  3. Zheng Da
    Replies:
    5
    Views:
    328
    Lionel B
    May 17, 2005
  4. tom arnall
    Replies:
    4
    Views:
    830
    tom arnall
    Feb 11, 2007
  5. Pascal Peyremorte
    Replies:
    0
    Views:
    427
    Pascal Peyremorte
    Dec 23, 2008
Loading...

Share This Page