0
public class LockExample {
public static void main(String[] args) {
    SharedResource sharedResource = new SharedResource();


    Thread A = new Thread(()->{for(int i = 0; i < 10; i++)sharedResource.print5();},"A");
    Thread B = new Thread(()->{for(int i = 0; i < 10; i++)sharedResource.print10();},"B");
    Thread C = new Thread(()->{for(int i = 0; i < 10; i++)sharedResource.print15();},"C");

    A.start();
    B.start();
    C.start();

    try {
        A.join();
        B.join();
        C.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("totall calls: "+sharedResource.getTotalCalls());


}
}

class SharedResource{
private int number  = 1;
private int totalCalls = 0;
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();

public void print5(){
    lock.lock();
    try {
        System.out.println("print5 running");
        while(number != 2)condition1.await();
        for(int i =0; i<5; i++){
            System.out.println(Thread.currentThread().getName()+"\t"+i);
        }
        totalCalls++;
        number = 3;
        condition3.signal();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }

}

public void print10(){
    lock.lock();
    try {
        System.out.println("print10 running");
        while(number != 1)condition2.await();
        for(int i =0; i<10; i++){
            System.out.println(Thread.currentThread().getName()+"\t"+i);
        }
        totalCalls++;
        number = 2;
        condition1.signal();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }

}

public void print15(){
    lock.lock();
    try {
        System.out.println("print15 running");
        while(number != 3)condition3.await();
        for(int i =0; i<15; i++){
            System.out.println(Thread.currentThread().getName()+"\t"+i);
        }
        totalCalls++;
        number = 1;
        condition2.signal();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }

}

public int getTotalCalls() {
    return totalCalls;
}
}

Hello guys, consider the code above, I thought the lock must lock the critical section that been surrounded by lock and unlock, but why the output look like this?

print5 running
print10 running
B   0
B   1
B   2
B   3
B   4
B   5
B   6
B   7
B   8
B   9
print10 running
print15 running
A   0
A   1

Why it go back to println("print10 running") again at output line 13? I think it signal the next thread which is print15() then print15() get the lock and lock everything. Hence print10 can not go in to lock section anymore. So why it print "print10 running" which is inside the lock section again?

  • Did you read [the documentation](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Condition.html#await--)? *The lock associated with this Condition is atomically released* – chrylis -cautiouslyoptimistic- Jul 31 '21 at 07:00
  • @chrylis-cautiouslyoptimistic- Yes, I know that. My question is, after print10() finished, it signal print15(), then print15() get the lock, right? But if you look at the output, above "print15 Running" there is a "print10 Running", it means print10() go over again and to the await() point in print10(). Since print15() already get the lock, why print10() can go into its lock section and print "print10 Running"? – commander spring Jul 31 '21 at 07:38

0 Answers0