当前位置: 主页 > JAVA语言

java 线程通信-Java中线程间通信的原理是什么?

发布时间:2023-06-23 11:09   浏览次数:次   作者:佚名

原理

线程通信可以被定义为:当多个线程共同操作共享的资源时,线程间通过某种方式互相告知自己的状态java 线程通信,以避免无效的资源争夺。线程间通信的方式可以有很多种:等待-通知、共享内存、管道流。每种方式用不同的方法来实现,这里首先介绍等待-通知的通信方式。“等待-通知”通信方式是Java中使用普遍的线程间通信方式。

java 线程通信_线程与线程的通信_java线程间通信实例

wait()方法的原理:首先,JVM会释放当前线程的对象锁监视器的Owner资格;其次,JVM会将当前线程移入监视器的WaitSet队列,而这些操作都和对象锁监视器是相关的。所以,wait()方法必须在synchronized同步块的内部调用。在当前线程执行wait()方法前,必须通过synchronized()方法成为对象锁的监视器的Owner。

java线程间通信实例_线程与线程的通信_java 线程通信

notify()方法的原理:JVM从对象锁的监视器的WaitSet队列移动一个线程到其EntryList队列,这些操作都与对象锁的监视器有关。所以,notify()方法也必须在synchronized同步块的内部调用。在执行notify()方法前,当前线程也必须通过synchronized()方法成为对象锁的监视器的Owner。

java线程间通信实例_java 线程通信_线程与线程的通信

笔试题

java 线程通信_java线程间通信实例_线程与线程的通信

有三个线程,保证线程3在线程2前执行,保证线程2在线程1前执行。

线程与线程的通信_java 线程通信_java线程间通信实例

解题


public class ObjectLockStudy {
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();
    public static void main(String[] args) throws InterruptedException {
        Thread c1 = new Thread(new C1());
        Thread c2 = new Thread(new C2());
        Thread c3 = new Thread(new C3());
        Thread.sleep(1000);
        c1.start();
        c2.start();
        c3.start();
    }
    
    static class C1 implements Runnable {
        @Override
        public void run() {
            synchronized (lock1) {
                try {
                    lock1.wait();
                    System.out.println(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    static class C2 implements Runnable {
        @Override
        public void run() {
            try {
                synchronized (lock2) {
                    lock2.wait();
                }
                System.out.println(2);
                synchronized (lock1) {
                    lock1.notify();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    static class C3 implements Runnable {
        @Override
        public void run() {
            System.out.println(3);
            synchronized (lock2) {
                lock2.notify();
            }
        }
    }
}

不难发现,线程的启动顺序虽然是”倒着“启动java 线程通信,但执行结果,却是严格按照题目要求的。