简体   繁体   中英

How to achieve synchronization of three threads using reentrant lock?

Below specified code snippet prints numbers in sequence with synchronizing three threads using wait() and notify() methods. But the requirement is to achieve the same using reentrant locking mechanism.

class JoinTask {

    private int currentRank = 1;

    public void doJob(int rank, int printNo) {
        synchronized (this) {
            while (rank != currentRank) {
                try {
                    System.out.println("going to wait by thread:" + printNo);
                    wait();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
            System.out.println("Job:" + printNo + " : " + currentRank);
            currentRank++;
            notifyAll();
        }
    }
}

public class ThreeThreadsPlay {

    public static void main(String[] args) {
        final JoinTask task = new JoinTask();

        Thread A = new Thread() {
            public void run() {
                int k = 1;
                for (int i = 1; i < 30; i++) {
                    task.doJob(k, 1);
                    k = k + 3;
                }}};

        Thread B = new Thread() {
            public void run() {
                int k = 2;
                for (int i = 1; i < 30; i++) {
                    task.doJob(k, 2);
                    k = k + 3;
                }}};

        Thread C = new Thread() {
            public void run() {
                int k = 3;
                for (int i = 1; i < 30; i++) {
                    task.doJob(k, 3);
                    k = k + 3;
                }}};
        C.start();
        B.start();
        A.start();
    }}

How can I achieve the same using reentrant locking?

Any other example using reentrant locking to provide such mechanism will also help. Furthermore, any information provided in this context will be highly appreciated.

Here's a proper implementation with ReentrantLock/Conditional . Note carefully the differences between this and what you attempted. The lock acquisition and release should really be handled in a try-finally block to avoid a lock being kept indefinitely, but you can find examples of that in other questions.

class JoinTask {

    private int currentRank = 1;
    final ReentrantLock l = new ReentrantLock();
    final Condition c = l.newCondition();

    public void doJob(int rank, int threadNumber) {
        l.lock();
        while(rank != currentRank) {
            c.await();
        }
        System.out.println("Job:" + threadNumber + " : " + currentRank);
        currentRank++;
        c.signalAll();
        l.unlock();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM