如何使用重入锁实现三个线程的同步?

时间:2017-07-08 11:18:18

标签: java multithreading

下面指定的代码片段依次打印数字,同时使用wait()和notify()方法同步三个线程。但要求是使用可重入锁定机制来实现相同的目标。

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();
    }}

如何使用重入锁定实现相同的目标?

使用重入锁定来提供此类机制的任何其他示例也会有所帮助。此外,在此背景下提供的任何信息都将受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

这是ReentrantLock/Conditional的正确实现。请仔细注意这与您尝试的内容之间的差异。锁定获取和释放应该在try-finally块中处理,以避免无限期地保存锁定,但是您可以在其他问题中找到这样的示例。

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();
    }
}