我们考虑这样一个场景:有多个学生需要在图书馆借一本书,这本书在同一时刻只能被一位学生占有,设计多线程的程序模拟这个借书和还书的场景。那么当这本书被一位同学借走时,程序就应当阻止其它线程的访问,因此借书就是多线程访问一个共享资源的方法,必须加同步锁,其它线程抢占不到资源会进入阻塞状态。还书就是一个线程释放资源,那么此时程序就应该去唤醒被阻塞的线程去抢占资源。这其实就是线程间通信的典型例子。线程间通信常用的方法有 wait()、notify()、notifyAll() 等。

以下是一个简单的 Java 多线程程序,使用 wait() 和 notify() 方法来演示线程之间的协作:

public class ThreadExample {
    public static void main(String[] args) {
        final Object lock = new Object(); // 创建一个共享的锁对象

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                synchronized (lock) {
                    try {
                        System.out.println("Thread 1 is waiting...");
                        lock.wait(); // 让线程1等待
                        System.out.println("Thread 1 is notified!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                synchronized (lock) {
                    System.out.println("Thread 2 is notifying...");
                    lock.notify(); // 唤醒等待的线程
                }
            }
        });

        t1.start(); // 启动线程1
        t2.start(); // 启动线程2
    }
}

在这个例子中,我们创建了一个共享的锁对象,然后定义了两个线程 t1 和 t2 。线程 t1 首先获得锁,并调用 wait()方法进入等待状态。线程 t2 获得锁,并调用 notify() 方法通知 t1 线程可以继续执行了。

最后,t1 线程被唤醒,并输出一条消息。

请注意,在使用 wait() 和 notify() 方法时,必须在同步块内部调用它们,否则会抛出 IllegalMonitorStateException 异常。此外,线程在调用 wait() 方法时会释放锁,直到被唤醒后才会重新获得锁。因此,如果在调用 wait() 方法之前没有获得锁,就会抛出 IllegalMonitorStateException 异常。

此外,还可以使用 Condition 和阻塞队列来控制线程通信,只做了解即可。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐