多线程的输出顺序[JAVA]

新手上路,请多包涵
package com.example.test;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ author ZHANG
 * @ create 2022/3/31$ 16:33$
 */
public class testLock {



        public static Lock lock = new ReentrantLock();
        public static int count = 0;

        public static Condition conditionA = lock.newCondition();
        public static Condition conditionB = lock.newCondition();

        public static void main(String[] args) {
            Thread t1 = new Thread() {
                @Override
                public void run() {
                    lock.lock();
                    if (count < 5) {
                        System.out.println("线程1未达到业务要求,暂停中,等待线程2处理到达到要求后唤醒");
                        try {
                            conditionA.await();// 暂停线程并释放锁
                            System.out.println("conditionA被唤醒");
                            System.out.println("-----即将再次睡着");
                            Thread.sleep(5000);
                            conditionB.await();
                            System.out.println("conditionB被唤醒");
                            System.out.println("我是线程1后面的代码");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    lock.unlock();
                }
            };

            Thread t2 = new Thread() {
                @Override
                public void run() {
                    lock.lock();
                    while (count < 10) {
                        count++;
                        System.out.println("线程2业务处理中: " + count);
                        try {
                            Thread.sleep(1000);
                            if (count == 5) {
                                conditionA.signal();
                                System.out.println("唤醒线程1");
                                lock.unlock();// 调用signal()方法后,线程2并不会释放锁,需要手动释放线程2才会执行
                                System.out.println("unlock后能否打印");
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    try {
                        lock.lock();// 不加这个会报java.lang.IllegalMonitorStateException
                        System.out.println("等待3秒后conditionB会被唤醒");
                        Thread.sleep(3000);
                        conditionB.signal();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    lock.unlock();// 这里释放锁,线程2执行完,线程1才会执行
                }
            };

            t1.start();
            t2.start();
            Thread.currentThread().interrupted();
        }

}

请问以上代码,为什么会输出一下结果:
线程1未达到业务要求,暂停中,等待线程2处理到达到要求后唤醒
线程2业务处理中: 1
线程2业务处理中: 2
线程2业务处理中: 3
线程2业务处理中: 4
线程2业务处理中: 5
唤醒线程1
unlock后能否打印
线程2业务处理中: 6
conditionA被唤醒
-----即将再次睡着
线程2业务处理中: 7
线程2业务处理中: 8
线程2业务处理中: 9
线程2业务处理中: 10
等待3秒后conditionB会被唤醒
conditionB被唤醒
我是线程1后面的代码

调用unlock()后是执行完后续的6-10,再释放锁,还是当即就释放?
为什么6会在conditionA被唤醒的前面?
感谢各位大佬解答!

阅读 1.4k
1 个回答

你 unlock 之后 t2 已经没有锁,之后所有的打印与 t1 种的相对关系都是没有任何保证的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题