user1643055
user1643055

Reputation: 21

Java- Method Synchronization

import java.util.logging.Level;
import java.util.logging.Logger;


public class test {

    private static void m1(final String a) {
        Thread t1 = new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                        System.out.print(a);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(test.class.getName()).log(Level.SEVERE,
                                                                   null, ex);
                    }
                }
            });
        t1.start();
    }

    private static void m2(final String a) {
        Thread t2 = new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                        System.out.print(" " + a);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(test.class.getName()).log(Level.SEVERE,
                                                                   null, ex);
                    }
                }
            });
        t2.start();
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            m1("Mihi");
            m2("Cherub");
            System.out.println("");
        }
    }
}

I wanna get output as MihiCherub MihiCherub Likewise 10 times

but now my output is "MihiMihi Cherub CherubMihi CherubMihiMih". I wanna sync my two methods and want to get result as mihicherub. Please Help..

Upvotes: 2

Views: 116

Answers (2)

Amit Deshpande
Amit Deshpande

Reputation: 19185

With the use of CountDownLatch you can achieve this but it not an efficient approach. I have modified your code as below.

import java.util.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;

public class test {

private static void m1(final String a, final CountDownLatch sharedCountDownLatch,
        final CountDownLatch masterCountDownLatch,
        final CountDownLatch doneCountDownLatch) {
    Thread t1 = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                sharedCountDownLatch.countDown();
                sharedCountDownLatch.await();
                System.out.print(a);
                masterCountDownLatch.countDown();

            } catch (InterruptedException ex) {
                Logger.getLogger(test.class.getName()).log(Level.SEVERE,
                        null, ex);
            } finally {
                doneCountDownLatch.countDown();
            }
        }
    });
    t1.start();
}

private static void m2(final String a, final CountDownLatch sharedCountDownLatch,
        final CountDownLatch masterCountDownLatch,
        final CountDownLatch doneCountDownLatch) {
    Thread t2 = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                sharedCountDownLatch.countDown();
                sharedCountDownLatch.await();
                masterCountDownLatch.await();
                System.out.print(" " + a + " ");
            } catch (InterruptedException ex) {
                Logger.getLogger(test.class.getName()).log(Level.SEVERE,
                        null, ex);
            } finally {
                doneCountDownLatch.countDown();
            }
        }
    });
    t2.start();
}

public static void main(String[] args) throws InterruptedException {
    for (int i = 0; i < 10; i++) {
        CountDownLatch doneCountDownLatch = new CountDownLatch(2);//CountDownLatch which will be to ensure that both threads executed.
        CountDownLatch sharedCountDownLatch = new CountDownLatch(2);//CountDownLatch that will be shared between both threads so that it will ensure that both threads are at the same execution point 
        CountDownLatch masterCountDownLatch = new CountDownLatch(1);//CountDownLatch which will be used when master thread completes it work
        m1("Mihi", sharedCountDownLatch, masterCountDownLatch,
                doneCountDownLatch);
        m2("Cherub", sharedCountDownLatch, masterCountDownLatch,
                doneCountDownLatch);
        System.out.println("");
        doneCountDownLatch.await();
    }
}
}

Which outputs as :

Mihi Cherub 
Mihi Cherub 
Mihi Cherub 
Mihi Cherub 
Mihi Cherub 
Mihi Cherub 
Mihi Cherub 
Mihi Cherub 
Mihi Cherub 
Mihi Cherub 

Upvotes: 0

Peter Lawrey
Peter Lawrey

Reputation: 533870

If you want to synchronize the behaviour, the best thing to do is to use one thread.

Thread are designed for relatively independent tasks, the more independent the better.

You can do what you want with synchronize, wait and notify but it will be relatively complicated (and pointless)

In your case, the println("") will execute before any of the other print(). Is that intented?

Upvotes: 2

Related Questions